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

  • 相关阅读:
    感觉每天打开自己的博客园, 想编程的心情就多了起来~~~
    算法图解相关代码整理
    github cli
    What's WebFlux ? And how to use it ? 一股有咖喱味的WebFlux简介
    style
    gradle 1
    gradle打包可运行jar
    外面下着雨
    天晴朗 看花儿多多开放
    Full Stack Reactive with React and Spring WebFlux
  • 原文地址:https://www.cnblogs.com/guangyun/p/4670119.html
Copyright © 2020-2023  润新知