cocos2d-x lua与c++简单交互

version: cocos2d-x 3.6


本文讲述lua与c++的一些简单交互:

  1. lua通过消息方式调用c++无参接口
  2. c++调用lua带参接口

1.通过消息方式调用无参接口

接收方监听消息命令,发送方发送消息请求。

  1. c++层监听消息
//在appdelegate启动时监听
void communication_cpp_lua::registerAllEvent()
{
    Director::getInstance()->getEventDispatcher()->addCustomEventListener("LUA_TO_CPP_FACEBOOK_LOGIN", std::bind(&communication_cpp_lua::facebookLogin, this, std::placeholders::_1));
}
void communication_cpp_lua::facebookLogin(EventCustom * evt)
{
    CCLOG("lua call cpp facebook login");
    //FX::PluginUser *pUser = FX::PluginManager::getInstance()->getPluginUser();
    //pUser->setLoginListener(this);
    //pUser->login();
}
  1. lua层发送命令请求
local event = cc.EventCustom:new("LUA_TO_CPP_FACEBOOK_LOGIN")
cc.Director:getInstance():getEventDispatcher():dispatchEvent(event)

请确保lua层发送消息前,c++层以注册了消息监听。


2.c++回调带参数的lua接口

c++调用lua无参数的接口也可使用消息方式,但是当调用带参数接口时,如下为直接调用方式:

  1. lua层接口 (记得函数要放在全局里面)
-------------------------------------------------------------
-- glocal
-- cpp direct call
-------------------------------------------------------------
-- parm: int string string string string
function cc.exports.onFacebookLogin(retCode, msg, id, name, picture)
    print("cc.exports.onFacebookLogin")
    -- TODO
end
  1. c++层调用

    注意事项:

  • 调用时lua函数所在文件的路径
  • 如果参数过多(或为数组),就将参数转为json,那么参数就只有一个了(json字符串)
void communication_cpp_lua::onLoginResult(FX::LoginResultCode ret, const char* msg)
{
    CCLOG("INFO: %s ---> retCode = %d, msg = %s", __FUNCTION__, ret, msg);
    FX::PluginUser *pUser = FX::PluginManager::getInstance()->getPluginUser();
    FX::UserInfo userinfo = pUser->getUserInfo();
        //注意函数调用,参数入栈顺序
    std::vector<std::pair<std::string,__String*>> parm;
    parm.push_back(std::make_pair("number", __String::createWithFormat("%d", ret)));
    parm.push_back(std::make_pair("string", __String::create(msg)));
    parm.push_back(std::make_pair("string", __String::create(userinfo.id)));
    parm.push_back(std::make_pair("string", __String::create(userinfo.name)));
    parm.push_back(std::make_pair("string", __String::create(userinfo.picture)));
        this->callLuaFuncWithParam("utils/communication_lua_cpp.lua", "onFacebookLogin", &parm);
}

//带参执行Lua方法无返回值
const void communication_cpp_lua::callLuaFuncWithParam(const char* luaFileName, const char* functionName, std::vector<std::pair<std::string,__String*>>* para)
{
    lua_State*  ls = LuaEngine::getInstance()->getLuaStack()->getLuaState();
    
    int isOpen = luaL_dofile(ls, FileUtils::getInstance()->fullPathForFilename(luaFileName).c_str());
    if(isOpen!=0)
        {
        CCLOG("Open Lua Error: %i", isOpen);
    }
    
    lua_getglobal(ls, functionName);
    int countnum = para->size();
    for (std::vector<std::pair<std::string,__String*>>::iterator itor = para->begin(); itor != para->end(); ++itor)
        {
        std::string typestr = itor->first;
                __String* strnr = itor->second;
                if(typestr == "string")
                {
                        lua_pushstring(ls, strnr->getCString());
                }
                else if(typestr == "number")
                {
                        lua_pushnumber(ls, strnr->intValue());
                }
                else if(typestr == "bool")
                {
                        lua_pushboolean(ls, strnr->boolValue());
                }
                else
                {
                        CCASSERT(false, "not surport this type");
                }
        }

    /*
     lua_call
     第二个参数:函数的参数个数
     第三个参数:函数返回值个数
     */
    lua_call(ls, countnum, 0);
 
//lua有返回值
//      const char* iResult = lua_tostring(ls, -1);
//      return iResult;
}