Sloppy's Blog

cocos2d-x绑定lua调用c++类

继上个cocos2d绑定js调用C++原生类后,今天继续出个Lua调用C++绑定类的文章,之前项目一直是手工Copy,c++的生成Lua中间层发现好麻烦,昨天借鉴js的修改,自动生成到项目结构中,省去修改,Copy的麻烦,不过吐槽下,Lua的genbindings.py,跟Js的genbindings.py感觉可以完全统一起来吗。为什么要分成两个,而且两个文件的风格不是一个人写的吗。一个留了custom_args的接口,一个不留。希望cocos团队能改进下。好了,开始(环境变量之类的,跟之前JS项目一样,也是基于cocos2d-x 3.11.1 Windows64)
PS:我的Android NDK用android-ndk-r10e不行的。结果我只能用r9d,主要是generate.py里引用的问题。llvm的版本不对

新建项目

运行命令行:
cocos new -l lua -d c:\cocos HelloLuaGame

新建c++类文件

三个文件,ErayUIHelper.h,ErayUIHper.cpp,Eray.h
ErayUIHelper.h:

#pragma once
#include "cocos2d.h"
class ErayUIHelper {
public:
    static void log(const std::string& value, cocos2d::Node* parent);
};

ErayUIHelper.cpp的实现如下:

#include "ErayUIHelper.h"
#include "scripting/lua-bindings/manual/CCLuaEngine.h"
using namespace cocos2d;
void ErayUIHelper::log(const std::string& value, cocos2d::Node* parent) {
    CCLOG("ErayUIHelper:%s",value.c_str());
    auto sp = Sprite::create("diamond2.png");
    parent->addChild(sp);
    sp->setPosition(Vec2(300.0f, 200.0f));
    LuaEngine::getInstance()->executeGlobalFunction("call_fromcpp");
}
Eray.h的内容就非常简单。主要是以后有其他的类,也包含到这个文件中
#pragma once
#include "ErayUIHelper.h"

添加ini文件

转到cocos2d-x/tools/tolua,根据对应的ini,新建一个coolexp.ini,可以跟上篇的JS中的ini一模一样,根据上篇一样,在genbindings.py添加frameworks_root变量,同时修改bindings-generator下的generator.py文件,添加script_path,可以参考JS篇

下面重要,tolua/genbindings.py,没有,这也是我吐槽的原因,没有我们来添加吧,大概在172行左右,添加如下代码:

# 打包自己的类绑定
custom_cmd_args = {'coolexp.ini': ('coolexp', 'lua_coolexp_auto'),
}
if len(custom_cmd_args) > 0:
    # 修改打包后文件至自定义的路径,跟coolexp.ini的目录一致
    output_dir = '%s/runtime-src/Classes/custom/scripting/auto' % frameworks_root 
    for key in custom_cmd_args.keys():
        args = custom_cmd_args[key]
        cfg = '%s/%s' % (tolua_root, key)
        print 'Generating bindings for %s...' % (key[:-4])
        command = '%s %s %s -s %s -t %s -o %s -n %s' % (python_bin, generator_py, cfg, args[0], target, output_dir, args[1])
        _run_cmd(command)
对了,不要用普通的记事本,修改python文件,因为他有严格的格式。不然会因为格式报错。 命令行下 运行tolua目录下的 genbindings.py 不出意外,应该会出现succeeds字样, ## 编译项目 打开proj.win32/HelloLuaGame.sln,添加文件,lua_coolexp_auto.hpp lua_coolexp_auto.cpp 在AppDelegate.cpp里添加 register_all_coolexp(stack->getLuaState());,当前要引用头文件:lua_coolexp_auto.hpp 编译项目。好了。 ## 添加c++调用Lua部分的代码 我们在src/目录下,修改main.lua文件,添加内容:
cc.exports.call_fromcpp = function()
    print("call_from cpp")
end

运行项目,在场景上会出现一张图片,控制台会出现相关的字符打印

最后的项目结构图,应该是这样的:
HelloLuaGame