【cocos2d-x + Lua(2) 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++;

———————————————————————————————————————————————————

ps:仙凡奇緣官網 http://www.xianfancoco.com (新版1.1已經上線)

cocos2dxQQ交流群:41131516

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM