cocos2dx lua和c++是如何通信的我们主要解决如下几个问题:
1,C++如何获取Lua里面的一个变量值?
2,C++如何获取Lua里面一个Table(Lua利用Table实现面向对象,那就能调用Lua里面的比较高级的引用方法)
3,C++如何访问Lua里面的一个方法?
4,C++如何访问Lua里面的一个带参数的方法?
5,C++如何访问Lua里面的一个带参数的方法并且带返回值?
如果以上问题都解决了,基本能满足我们游戏开发中遇到的数据通信的问题;
定义出了更好用的C++/lua数据通讯类库
下面我直接贴函数了,大家自取:
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++;