如何在cocos2d c++代码中调用lua以及探究

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在cocos2d c++代码中调用lua以及探究相关的知识,希望对你有一定的参考价值。

如何在cocos2d c++代码中调用lua

在AppDelegate 中加入了
#include"Lua_extensions_CCB.h"
#include"CCLuaEngine.h"
#include"Lua_web_socket.h"

查到代码加载lua脚步引擎
官方原话注册引擎
CCLuaEngine*pEngine=CCLuaEngine::defaultEngine();
CCScriptEngineManager::sharedManager()->setScriptEngine(pEngine);

和ccb有关的lua
CCLuaStack*pStack=pEngine->getLuaStack();
lua_State*tolua_s=pStack->getLuaState();
tolua_extensions_ccb_open(tolua_s);

和web_socket 相关的lua
pStack=pEngine->getLuaStack();
tolua_s=pStack->getLuaState();
tolua_web_socket_open(tolua_s);

pEngine->executeScriptFile("luaScript/controller.lua");
结束

打开luaScript/controller.lua仔细研究

-- avoidmemory leak
collectgarbage("setpause",100)
collectgarbage("setstepmul",5000)

require"luaScript/mainMenu"
----------------

-- run
local scene =CCScene:create()
scene:addChild(CreateTestMenu())
CCDirector:sharedDirector():runWithScene(scene)

到这里如果熟悉cocos2dx 的朋友就很熟悉了
不错,这里是cocos2d中lua的使用方法和c++中调用差别不大!

但是还没有完

Cocos2dx 对lua的封装是很好的!

如果不熟悉c++与lua的绑定的代码下面的不建议看
C++与lua的绑定传送门

关于cocos2d 与 lua绑定的代码的探究

//打开"CCLuaEngine.h"

单例实现CCScripEngineProtocol
后期应该支持不仅仅只是lua的脚本引擎

头文件有很多方法

挑一个看看
virtualintexecuteNodeEvent(CCNode*pNode,intnAction);

intCCLuaEngine::executeNodeEvent(CCNode*pNode,intnAction)

intnHandler=pNode->getScriptHandler();
if(!nHandler)return0;

switch(nAction)

casekCCNodeOnEnter:
m_stack->pushString("enter");
break;

casekCCNodeOnExit:
m_stack->pushString("exit");
break;

casekCCNodeOnEnterTransitionDidFinish:
m_stack->pushString("enterTransitionFinish");
break;

casekCCNodeOnExitTransitionDidStart:
m_stack->pushString("exitTransitionStart");
break;

casekCCNodeOnCleanup:
m_stack->pushString("cleanup");
break;

default:
return0;

intret=m_stack->executeFunctionByHandler(nHandler,1);
m_stack->clean();
returnret;


这里是进入CCNode后的一些消息函数的处理

不管
intret=m_stack->executeFunctionByHandler(nHandler,1);

最终是回到了CCLuaStack

调用了executeFunctionByHandler(nHandler,1);

继续探究

intCCLuaStack::executeFunctionByHandler(intnHandler,intnumArgs)

intret=0;
if(pushFunctionByHandler(nHandler)) /* L: ... arg1 arg2 ... func */

if(numArgs>0)

lua_insert(m_state,-(numArgs+1)); /* L: ... func arg1 arg2 ... */

ret=executeFunction(numArgs);

lua_settop(m_state,0);
returnret;


可以看到一些和lua与c++联系的代码了

看看这个类的初始化

boolCCLuaStack::init(void)

m_state=lua_open();
luaL_openlibs(m_state);
tolua_Cocos2d_open(m_state);
toluafix_open(m_state);

// Register our version of the global "print"function
constluaL_regglobal_functions[]=
"print",lua_print,
NULL,NULL
;
luaL_register(m_state,"_G",global_functions);
tolua_CocoStudio_open(m_state);
#if(CC_TARGET_PLATFORM==CC_PLATFORM_ios||CC_TARGET_PLATFORM==CC_PLATFORM_MAC)
CCLuaObjcBridge::luaopen_luaoc(m_state);
#endif
register_all_cocos2dx_manual(m_state);
register_all_cocos2dx_extension_manual(m_state);
register_all_cocos2dx_studio_manual(m_state);
// add cocos2dx loader
addLuaLoader(cocos2dx_lua_loader);

returntrue;


这个里的方法看名称应该是注册 coco2dx 中的类到
C++中

register_all_cocos2dx_manual(m_state);
register_all_cocos2dx_extension_manual(m_state);
register_all_cocos2dx_studio_manual(m_state);

详细看
Coco2dx-studio 先不看

头文件
lua_cocos2dx_manual.h

#ifdef__cplusplus
extern"C"
#endif
#include"tolua++.h"
#ifdef__cplusplus

#endif

LUA_APIintregister_all_cocos2dx_manual(lua_State*tolua_S);

头文件
lua_cocos2dx_extensions_manual
#ifdef__cplusplus
extern"C"
#endif
#include"tolua++.h"
#ifdef__cplusplus

#endif

LUA_APIintregister_all_cocos2dx_extension_manual(lua_State*tolua_S);

惊人的相似
看看tolua++.h
真相快水落石出了

这里定义了lua所以用到全部函数

这里是头部,
/* tolua
** Support code for Lua bindings.
** Written by Waldemar Celes
** TeCGraf/PUC-Rio
** Apr 2003
** $Id: $
*/

/* This code is free software; you can redistributeit and/or modify it.
** The software provided hereunder is on an"as is" basis, and
** the author has no obligation to providemaintenance, support, updates,
** enhancements, or modifications.
*/

原来tolua也是lua封装起来的函数库,大师2003 4月就写好了
相当的牛

好上面只看了lua_cocos2dx_extensions_manual.h的头文件
cpp文件我们也一看详情
我发现注册了一些函数
但是不是全部

在CCLuaStack::init()
方法里还有
tolua_Cocos2d_open(m_state);
这个方法
相应的头文件是LuaCocos2d..h
可以打开看看详情

Luacocos2d..cpp注册了n多函数
我用注册是相对于lua而言

Luacocos2d.cpp代码贼多
有兴趣的童鞋可以看看

看来什么时间要看看cocos2d studio 的代码
紧跟时代的步伐
不能老是cocos builder
参考技术A 在AppDelegate 中加入了
#include"Lua_extensions_CCB.h"
#include"CCLuaEngine.h"
#include"Lua_web_socket.h"

查到代码加载lua脚步引擎
官方原话注册引擎
CCLuaEngine*pEngine=CCLuaEngine::defaultEngine();
CCScriptEngineManager::sharedManager()->setScriptEngine(pEngine);

和ccb有关的lua
CCLuaStack*pStack=pEngine->getLuaStack();
lua_State*tolua_s=pStack->getLuaState();
tolua_extensions_ccb_open(tolua_s);

和web_socket 相关的lua
pStack=pEngine->getLuaStack();
tolua_s=pStack->getLuaState();
tolua_web_socket_open(tolua_s);

pEngine->executeScriptFile("luaScript/controller.lua");
结束

打开luaScript/controller.lua仔细研究

-- avoidmemory leak
collectgarbage("setpause",100)
collectgarbage("setstepmul",5000)

require"luaScript/mainMenu"
----------------

-- run
local scene =CCScene:create()
scene:addChild(CreateTestMenu())
CCDirector:sharedDirector():runWithScene(scene)

到这里如果熟悉cocos2dx 的朋友就很熟悉了
不错,这里是cocos2d中lua的使用方法和c++中调用差别不大!

但是还没有完

Cocos2dx 对lua的封装是很好的!

如果不熟悉c++与lua的绑定的代码下面的不建议看
C++与lua的绑定传送门

关于cocos2d 与 lua绑定的代码的探究

//打开"CCLuaEngine.h"

单例实现CCScripEngineProtocol
后期应该支持不仅仅只是lua的脚本引擎

头文件有很多方法

挑一个看看
virtualintexecuteNodeEvent(CCNode*pNode,intnAction);

intCCLuaEngine::executeNodeEvent(CCNode*pNode,intnAction)

intnHandler=pNode->getScriptHandler();
if(!nHandler)return0;

switch(nAction)

casekCCNodeOnEnter:
m_stack->pushString("enter");
break;

casekCCNodeOnExit:
m_stack->pushString("exit");
break;

casekCCNodeOnEnterTransitionDidFinish:
m_stack->pushString("enterTransitionFinish");
break;

casekCCNodeOnExitTransitionDidStart:
m_stack->pushString("exitTransitionStart");
break;

casekCCNodeOnCleanup:
m_stack->pushString("cleanup");
break;

default:
return0;

intret=m_stack->executeFunctionByHandler(nHandler,1);
m_stack->clean();
returnret;


这里是进入CCNode后的一些消息函数的处理

不管
intret=m_stack->executeFunctionByHandler(nHandler,1);

最终是回到了CCLuaStack

调用了executeFunctionByHandler(nHandler,1);

继续探究

intCCLuaStack::executeFunctionByHandler(intnHandler,intnumArgs)

intret=0;
if(pushFunctionByHandler(nHandler)) /* L: ... arg1 arg2 ... func */

if(numArgs>0)

lua_insert(m_state,-(numArgs+1)); /* L: ... func arg1 arg2 ... */

ret=executeFunction(numArgs);

lua_settop(m_state,0);
returnret;


可以看到一些和lua与c++联系的代码了

看看这个类的初始化

boolCCLuaStack::init(void)

m_state=lua_open();
luaL_openlibs(m_state);
tolua_Cocos2d_open(m_state);
toluafix_open(m_state);

// Register our version of the global "print"function
constluaL_regglobal_functions[]=
"print",lua_print,
NULL,NULL
;
luaL_register(m_state,"_G",global_functions);
tolua_CocoStudio_open(m_state);
#if(CC_TARGET_PLATFORM==CC_PLATFORM_IOS__CC_TARGET_PLATFORM==CC_PLATFORM_MAC)
CCLuaObjcBridge::luaopen_luaoc(m_state);
#endif
register_all_cocos2dx_manual(m_state);
register_all_cocos2dx_extension_manual(m_state);
register_all_cocos2dx_studio_manual(m_state);
// add cocos2dx loader
addLuaLoader(cocos2dx_lua_loader);

returntrue;


这个里的方法看名称应该是注册 coco2dx 中的类到
C++中

register_all_cocos2dx_manual(m_state);
register_all_cocos2dx_extension_manual(m_state);
register_all_cocos2dx_studio_manual(m_state);

详细看
Coco2dx-studio 先不看

头文件
lua_cocos2dx_manual.h

#ifdef__cplusplus
extern"C"
#endif
#include"tolua++.h"
#ifdef__cplusplus

#endif

LUA_APIintregister_all_cocos2dx_manual(lua_State*tolua_S);

头文件
lua_cocos2dx_extensions_manual
#ifdef__cplusplus
extern"C"
#endif
#include"tolua++.h"
#ifdef__cplusplus

#endif

LUA_APIintregister_all_cocos2dx_extension_manual(lua_State*tolua_S);

惊人的相似
看看tolua++.h
真相快水落石出了

这里定义了lua所以用到全部函数

这里是头部,
/* tolua
** Support code for Lua bindings.
** Written by Waldemar Celes
** TeCGraf/PUC-Rio
** Apr 2003
** $Id: $
*/

/* This code is free software; you can redistributeit and/or modify it.
** The software provided hereunder is on an"as is" basis, and
** the author has no obligation to providemaintenance, support, updates,
** enhancements, or modifications.
*/

原来tolua也是lua封装起来的函数库,大师2003 4月就写好了
相当的牛

好上面只看了lua_cocos2dx_extensions_manual.h的头文件
cpp文件我们也一看详情
我发现注册了一些函数
但是不是全部

在CCLuaStack::init()
方法里还有
tolua_Cocos2d_open(m_state);
这个方法
相应的头文件是LuaCocos2d..h
可以打开看看详情

Luacocos2d..cpp注册了n多函数
我用注册是相对于lua而言

Luacocos2d.cpp代码贼多
有兴趣的童鞋可以看看

看来什么时间要看看cocos2d studio 的代码
紧跟时代的步伐
不能老是cocos builder本回答被提问者和网友采纳

如何让lua调用一个向lua返回多个值的c++函数

【中文标题】如何让lua调用一个向lua返回多个值的c++函数【英文标题】:how to have lua call a c++ function that returns multiple values to lua 【发布时间】:2021-12-13 05:46:33 【问题描述】:

我的代码(部分) c++:

lua_register(L, "GetPosition", lua_GetPosition);

int lua_GetPosition(lua_State* L)

    Entity e = static_cast<Entity>(lua_tointeger(L, 1));
    TransformComponent* trans = TransformComponentPool.GetComponentByEntity(e);
    if (trans != nullptr)
    
        lua_pushnumber(L, trans->transform->position.x);
        lua_pushnumber(L, trans->transform->position.y);
        lua_pushnumber(L, trans->transform->position.z);
    
    else
    
        lua_pushnumber(L, 0);
        lua_pushnumber(L,0);
        lua_pushnumber(L, 0);
        LOG_ERROR("Transform not found");
    
    return 1;

卢阿:

local x = 69
local y = 69
local z = 69
x,y,z = GetPosition(e)
print("xyz =",x,y,z)

我预计“xyz = 1.0 1.0 1.0” 我得到“xyz = 1.0 nil nil”

什么是正确的方法让 lua 看到所有的返回值?

【问题讨论】:

您需要返回您推送的值的数量:return 3 你可以简单地写local x, y, z = GetPosition(e) btw。这里不需要用值初始化 x,y,z。 【参考方案1】:

当 Lua 调用你的函数时,它会检查它的返回值以找出它应该从堆栈中获取多少值。在你的情况下是1。 Lua 怎么知道你想要返回多少推送的值?

来自Lua 5.4 Reference Manual 4.6 Functions and Types:

为了与 Lua 正确通信,C 函数必须使用 遵循协议,它定义了参数和结果的方式 传递:一个 C 函数在它的堆栈中从 Lua 接收它的参数 直接顺序(首先推送第一个参数)。所以,当 函数启动,lua_gettop(L) 返回参数个数 由函数接收。第一个参数(如果有)位于索引 1 它的最后一个参数在索引 lua_gettop(L) 处。 返回值到 Lua,一个 C 函数只是将它们直接推入堆栈 (首先推送第一个结果),并且 在 C 中返回数量 结果。 堆栈中结果下方的任何其他值都将是 被 Lua 正确丢弃。像 Lua 函数一样,C 函数由 Lua 也可以返回很多结果。

例如,以下函数接收可变数量的 数字参数并返回它们的平均值和它们的总和:

 static int foo (lua_State *L) 
   int n = lua_gettop(L);    /* number of arguments */
   lua_Number sum = 0.0;
   int i;
   for (i = 1; i <= n; i++) 
     if (!lua_isnumber(L, i)) 
       lua_pushliteral(L, "incorrect argument");
       lua_error(L);
     
     sum += lua_tonumber(L, i);
   
   lua_pushnumber(L, sum/n);        /* first result */
   lua_pushnumber(L, sum);         /* second result */
   return 2;                   /* number of results */
 

【讨论】:

以上是关于如何在cocos2d c++代码中调用lua以及探究的主要内容,如果未能解决你的问题,请参考以下文章

Lua - C++ 集成:从 C++ 调用表中的函数

如何让lua调用一个向lua返回多个值的c++函数

lua调用java过程

嵌入在 C++ socket.http 中的 LUA [错误:尝试调用 nil 值]

quick cocos Lua与OC互相回调,苹果内购机制

Unity3D热更新之LuaFramework篇[05]--Lua脚本调用c#以及如何在Lua中使用Dotween