Cocos2d-x中Lua与C++通信
参考文章地址:http://www.himigame.com/lua-game/1343.html
几个Lua中的API介绍
int luaL_dofile (lua_State *L, const char *filename) :
加载并运行指定文件,没有错误返回0
void lua_settop (lua_State *L, int index):
参数允许传入任何可接受的索引以及 0 。 它将把堆栈的栈顶设为这个索引。 如果新的栈顶比原来的大,超出部分的新元素将被填为 nil 。 如果 index 为 0 ,把栈上所有元素移除。
void lua_getglobal (lua_State *L, const char *name):
把全局变量 name 里的值压入堆栈。
void lua_pop (lua_State *L, int n):
从堆栈中弹出 n
个元素。相当于清除!
void lua_pushstring (lua_State *L, const char *s):
把指针 s 指向的以零结尾的字符串压栈。 Lua 对这个字符串做一次内存拷贝(或是复用一个拷贝), 因此 s 处的内存在函数返回后,可以释放掉或是重用于其它用途。 字符串中不能包含有零字符;第一个碰到的零字符会认为是字符串的结束。
更多的API请参考:http://www.codingnow.com/2000/download/lua_manual.html
C++声明
#ifndef __LUA_TEST_H__ #define __LUA_TEST_H__ #include "cocos2d.h" //引入lua库,由于lua是用C语言实现的,所以需要添加extern "C" EXTERN_C{ #include "lua.h" #include "lualib.h" #include "lauxlib.h" } #include "CCLuaEngine.h" class LuaTest { public: /********* 获取Lua中的全局字符串 *********/ const char* getLuaString(const char* script,const char* varName); /********* 获取Lua中全局table的字符串 *********/ const char* getLuaString4Table(const char* script,const char* table, const char* varName); /********* 打印Lua中全局table的元素 *********/ void printLuaTable(const char* script, const char* table); /********* C++调用Lua中的全局函数 *********/ int callLuaAdd(const char* script, int a,int b); /********* Lua调用C++的静态函数 *********/ void luaCallCppFunctionTest(); /** 获取文件全路径 **/ static const char* getFullPath(const char* file); /** C++静态函数需要注册才能被Lua调用,而且参数为一个lua_State*,返回值为int **/ static int cppAdd(lua_State* L); }; #endif
C++实现
#include "LuaTest.h" USING_NS_CC; /********* 获取Lua中的全局字符串 *********/ const char* LuaTest::getLuaString(const char* script,const char* varName){ lua_State* L = CCLuaEngine::defaultEngine()->getLuaStack()->getLuaState(); //加载并运行脚本 int isOpen = luaL_dofile(L, LuaTest::getFullPath(script)); if (isOpen != 0) { CCLOG("execute script %s failure. error_code=%d error_msg=%s",script,isOpen,lua_tostring(L,-1)); return NULL; } //Lua中的全局字符串varName入栈 lua_getglobal(L,varName); //判断栈顶元素是否字符串 if(lua_isstring(L,-1)){ //返回栈顶字符串 return lua_tostring(L,-1); } return NULL; } /********* 获取Lua中全局table的字符串 *********/ const char* LuaTest::getLuaString4Table(const char* script,const char* table, const char* varName){ lua_State* L = CCLuaEngine::defaultEngine()->getLuaStack()->getLuaState(); //加载并运行脚本 int isOpen = luaL_dofile(L,LuaTest::getFullPath(script)); if (isOpen != 0) { CCLOG("execute script %s failure. error_code=%d error_msg=%s",script,isOpen,lua_tostring(L,-1)); return NULL; } //对Lua中的table执行压栈 lua_getglobal(L,table); //如果栈顶元素是一个table if(lua_istable(L,-1)){ //key入栈 lua_pushstring(L,varName); //当前栈顶元素为varName,索引为-1;table在varName下面,索引为-2 //获取table中varName元素的值,第二个参数为当前tabele在栈中的索引位置 lua_gettable(L,-2); //当前栈顶元素为table中varName元素的值 const char* value = lua_tostring(L,-1); //从栈中弹出一个元素 lua_pop(L,1); return value; } return NULL; } /********* 打印Lua中全局table的元素 *********/ void LuaTest::printLuaTable(const char* script, const char* table){ lua_State* L = CCLuaEngine::defaultEngine()->getLuaStack()->getLuaState(); //加载并运行脚本 int isOpen = luaL_dofile(L,LuaTest::getFullPath(script)); if (isOpen != 0) { CCLOG("execute script %s failure. error_code=%d error_msg=%s",script,isOpen,lua_tostring(L,-1)); return; } //table入栈 lua_getglobal(L,table); //获取栈顶索引(该方法相当于获取栈中元素的个数,因为栈的索引是从1开始往上升的) int top = lua_gettop(L); //由于lua_next会先对栈执行一次弹出操作,然后再从table中获取一对key-value入栈,所以先放一个nil在栈顶 lua_pushnil(L); if (lua_istable(L,top)) { CCLOG("iterator is start.. table=%s",table); //迭代table while (lua_next(L,top)) //key出栈,key-value入栈(如果table中还有元素) { //获取key const char* key = lua_tostring(L,-2); //获取value const char* value = lua_tostring(L,-1); CCLOG("%s - %s",key,value); lua_pop(L,1);//value出栈 } CCLOG("iterator is end.."); lua_pop(L,1);//key出栈 } } /********* C++调用Lua中的全局函数 *********/ int LuaTest::callLuaAdd(const char* script, int a,int b){ lua_State* L = CCLuaEngine::defaultEngine()->getLuaStack()->getLuaState(); //lua函数入栈 lua_getglobal(L,"add"); if (lua_isfunction(L,-1)) { //参数入栈 lua_pushnumber(L,a); lua_pushnumber(L,b); //调用lua函数:第二个参数是函数的参数个数,第三个参数是函数的返回值个数 lua_call(L,2,1); //获取返回值 if (lua_isnumber(L,-1)) { return lua_tonumber(L,-1); } } return NULL; } /********* Lua调用C++的静态函数 *********/ void LuaTest::luaCallCppFunctionTest(){ lua_State* L = CCLuaEngine::defaultEngine()->getLuaStack()->getLuaState(); //注册C++函数(函数必须是静态的) lua_register(L,"cppAdd",LuaTest::cppAdd); //加载并运行lua脚本 luaL_dofile(L,LuaTest::getFullPath("script/testCallCppFun.lua")); } int add(int a, int b){ return a+b; } /** C++静态函数 **/ int LuaTest::cppAdd(lua_State* L){ //从栈中获取参数 int a = luaL_checknumber(L,-1); int b = luaL_checknumber(L,-2); //调用C++中的add函数 int result = add(a,b); //对结果入栈 lua_pushnumber(L,result); return 1;//返回值个数 } const char* LuaTest::getFullPath(const char* file){ //return CCFileUtils::sharedFileUtils()->fullPathForFilename(file).c_str(); std::string filePath = CCFileUtils::sharedFileUtils()->fullPathForFilename(file).c_str(); CCLOG(filePath.c_str()); return file; }
Lua代码
test.lua的代码:
--Lua中的字符串 luaStr = "this is a string form lua" luaTable = { name="linchaolong",age="unknow",sex="man"} function add(a,b) return a+b; end
testCallCppFun.lua的代码:
result = cppAdd(1,1) print("call c++ add function result = "..result)
测试代码
LuaTest* lua = new LuaTest; //获取Lua中的luaStr字符串 CCLOG("lua string = %s",lua->getLuaString("script/test.lua","luaStr")); //获取Lua中table的字符串 CCLOG("lua table string = %s",lua->getLuaString4Table("script/test.lua","luaTable","name")); //打印table中的元素 lua->printLuaTable("script/test.lua","luaTable"); //调用lua中的add函数 lua->callLuaAdd("script/test.lua",1,1); //Lua调用C++中的函数 lua->luaCallCppFunctionTest(); delete lua;
注意:
posted on 2014-07-11 16:06 linchaolong 阅读(346) 评论(0) 编辑 收藏 举报