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++;