我們主要解決如下幾個問題:
轉載注明出處: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++;
———————————————————————————————————————————————————
ps:仙凡奇緣官網 http://www.xianfancoco.com (新版1.1已經上線)
cocos2dxQQ交流群:41131516