Cocos2dx-C++和Lua数据通讯
本文转载于:http://www.cnblogs.com/zisou/p/cocos2dx-lua2.html
我们主要解决如下几个问题:
1,C++如何获取Lua里面的一个变量值?
2,C++如何获取Lua里面一个Table(Lua利用Table实现面向对象,那就能调用Lua里面的比较高级的引用方法)
3,C++如何访问Lua里面的一个方法?
4,C++如何访问Lua里面的一个带参数的方法?
5,C++如何访问Lua里面的一个带参数的方法并且带返回值?
如果以上问题都解决了,基本能满足我们游戏开发中遇到的数据通信的问题;
我整合了HIMI哥哥这篇教程里面的思路,重构了一下,定义出了更好用的C++/lua数据通讯类库;
http://blog.csdn.net/xiaominghimi/article/details/8816887
下面我直接贴函数了,大家自取:
PublicSendLuaData.h
// PublicSendLuaData.cpp // // Lua and C++/C 交互类 #ifndef __PublicSendLuaData__ #define __PublicSendLuaData__ #include "cocos2d.h" using namespace cocos2d; using namespace std; extern "C" { #include "lua.h" #include "lualib.h" #include "lauxlib.h" }; class PublicSendLuaData{ public: static PublicSendLuaData* getInstance(); /* 直接获取Lua中得变量名值 文件名 luaFileName 变量名 varName */ const char* getLuaVarString(const char* luaFileName,const char* varName); /* 获取Lua中一个表中得节点名,甚至方法 文件名luaFileName 方法名varName 节点名 */ const char* getLuaVarOneOfTable(const char* luaFileName,const char* varName,const char* keyName); /* 调用Lua全局Table lua文件名luaFileName table变量名varName */ const char* getLuaVarTable(const char* luaFileName,const char* varName); /* 带参数有返回 文件名luaFileName 方法名functionName 参数序列arraypar 参数类型arraypartype */ const char* callLuaFuncParReturn(const char* luaFileName,const char* functionName,CCArray* arraypar,CCArray* arraypartype); /* 带参数无返回 文件名luaFileName 方法名functionName 参数序列arraypar 参数类型arraypartype */ const void callLuaFuncPar(const char* luaFileName,const char* functionName,CCArray* arraypar,CCArray* arraypartype); private: static bool _isFirst; static PublicSendLuaData* m_instance; const char* getFileFullPath(const char* fileName); ~PublicSendLuaData(); }; #endif
PublicSendLuaData.cpp
// PublicSendLuaData.cpp // // Created by ZISOU-YSJ // // Lua and C++/c 交互类 #include "PublicSendLuaData.h" #include "CCLuaEngine.h" PublicSendLuaData* PublicSendLuaData::m_instance = NULL; PublicSendLuaData* PublicSendLuaData::getInstance(){ if(!m_instance) { m_instance = new PublicSendLuaData(); } return m_instance; } //获取变量名值 const char* PublicSendLuaData::getLuaVarString(const char* luaFileName,const char* varName){ lua_State* ls = CCLuaEngine::defaultEngine()->getLuaStack()->getLuaState(); int isOpen = luaL_dofile(ls, getFileFullPath(luaFileName)); if(isOpen!=0){ CCLOG("Open Lua Error: %i", isOpen); return NULL; } lua_settop(ls, 0); lua_getglobal(ls, varName); int statesCode = lua_isstring(ls, 1); if(statesCode!=1){ CCLOG("Open Lua Error: %i", statesCode); return NULL; } const char* str = lua_tostring(ls, 1); lua_pop(ls, 1); return str; } const char* PublicSendLuaData::getLuaVarOneOfTable(const char* luaFileName,const char* varName,const char* keyName){ lua_State* ls = CCLuaEngine::defaultEngine()->getLuaStack()->getLuaState(); int isOpen = luaL_dofile(ls, getFileFullPath(luaFileName)); if(isOpen!=0){ CCLOG("Open Lua Error: %i", isOpen); return NULL; } lua_getglobal(ls, varName); int statesCode = lua_istable(ls, -1); if(statesCode!=1){ CCLOG("Open Lua Error: %i", statesCode); return NULL; } lua_pushstring(ls, keyName); lua_gettable(ls, -2); const char* valueString = lua_tostring(ls, -1); lua_pop(ls, -1); return valueString; } //执行Lua表,返回表结构 const char* PublicSendLuaData::getLuaVarTable(const char* luaFileName,const char* varName){ lua_State* ls = CCLuaEngine::defaultEngine()->getLuaStack()->getLuaState(); int isOpen = luaL_dofile(ls, getFileFullPath(luaFileName)); if(isOpen!=0){ CCLOG("Open Lua Error: %i", isOpen); return NULL; } lua_getglobal(ls, varName); int it = lua_gettop(ls); lua_pushnil(ls); string result=""; while(lua_next(ls, it)) { string key = lua_tostring(ls, -2); string value = lua_tostring(ls, -1); result=result+key+":"+value+"\t"; lua_pop(ls, 1); } lua_pop(ls, 1); return result.c_str(); } //带参执行Lua方法有返回值 const char* PublicSendLuaData::callLuaFuncParReturn(const char* luaFileName,const char* functionName,CCArray* arraypar,CCArray* arraypartype){ lua_State* ls = CCLuaEngine::defaultEngine()->getLuaStack()->getLuaState(); int isOpen = luaL_dofile(ls, getFileFullPath(luaFileName)); if(isOpen!=0){ CCLOG("Open Lua Error: %i", isOpen); return NULL; } lua_getglobal(ls, functionName); int countnum = arraypar->count(); if(countnum>0) { for (int i = 0; i<arraypar->count(); i++) { CCString* typestr = (CCString*)arraypartype->objectAtIndex(i); CCString* strnr = (CCString*)arraypar->objectAtIndex(i); if(typestr->isEqual(CCString::create("string"))) { lua_pushstring(ls, strnr->getCString()); } else if(typestr->isEqual(CCString::create("int"))) { lua_pushnumber(ls, strnr->intValue()); } else if(typestr->isEqual(CCString::create("bool"))) { lua_pushboolean(ls, strnr->boolValue()); } } } /* lua_call 第一个参数:函数的参数个数 第二个参数:函数返回值个数 */ lua_call(ls, countnum, 1); const char* iResult = lua_tostring(ls, -1); return iResult; } //带参执行Lua方法无返回值 const void PublicSendLuaData::callLuaFuncPar(const char* luaFileName,const char* functionName,CCArray* arraypar,CCArray* arraypartype){ lua_State* ls = CCLuaEngine::defaultEngine()->getLuaStack()->getLuaState(); int isOpen = luaL_dofile(ls, getFileFullPath(luaFileName)); if(isOpen!=0){ CCLOG("Open Lua Error: %i", isOpen); } lua_getglobal(ls, functionName); int countnum = arraypar->count(); if(countnum>0) { for (int i = 0; i<arraypar->count(); i++) { CCString* typestr = (CCString*)arraypartype->objectAtIndex(i); CCString* strnr = (CCString*)arraypar->objectAtIndex(i); if(typestr->isEqual(CCString::create("string"))) { lua_pushstring(ls, strnr->getCString()); } else if(typestr->isEqual(CCString::create("int"))) { lua_pushnumber(ls, strnr->intValue()); } else if(typestr->isEqual(CCString::create("bool"))) { lua_pushboolean(ls, strnr->boolValue()); } } } /* lua_call 第一个参数:函数的参数个数 第二个参数:函数返回值个数 */ lua_call(ls, countnum, 0); } const char* PublicSendLuaData::getFileFullPath(const char* fileName){ return CCFileUtils::sharedFileUtils()->fullPathForFilename(fileName).c_str(); } PublicSendLuaData::~PublicSendLuaData(){ CC_SAFE_DELETE(m_instance); m_instance=NULL; }
上面都有注释,我就不详细去一一赘述,不过以上方法能满足大部分在C++中访问Lua的各种需求;
我这里就只说一个例子如:
CCArray* arraypar = CCArray::create(); arraypar->addObject(CCString::create("参数值")); CCArray* arraytype =CCArray::create(); arraytype->addObject(CCString::create("string")); PublicSendLuaData::getInstance()->callLuaFuncPar("Lua文件名", "参数名", arraypar, arraytype);
这个就是具体调用Lua里面一个带参数全局方法的语句;
我写了一个类型匹配的方法:
if(typestr->isEqual(CCString::create("string"))) { lua_pushstring(ls, strnr->getCString()); } else if(typestr->isEqual(CCString::create("int"))) { lua_pushnumber(ls, strnr->intValue()); } else if(typestr->isEqual(CCString::create("bool"))) { lua_pushboolean(ls, strnr->boolValue()); }
大家使用的时候注意匹配一下这个就行;
那又人问了,如果在Lua中访问C++函数怎么办呢?还记得我文章第一篇中得Lua调用C++函数类的方法呢?
我提倡使用tolua++工具类去坐Lua访问C++;