cocos2dx3.0rc导出自定义类到lua的方法详细步骤

本文介绍如何使用Cocos2d-x将自定义C++类绑定到Lua运行时,包括生成源代码、添加自定义类、创建Lua绑定文件等步骤。

转自:http://www.cocoachina.com/bbs/read.php?tid=196416

我写了一个用3.0的工具导出类到lua,自动生成代码的方法。

以前要导出c++类到lua,就得手动维护pkg文件,那简直就是噩梦,3.0以后就会感觉生活很轻松了。

下面我就在说下具体做法。
1、安装必要的库和工具包,以及配置相关环境变量,请按照cocos2d-x-3.0rc0\tools\tolua\README.mdown说得去做,不做赘述。

2、写c++类(我测试用的是cocos2d-x-3.0rc0\tests\lua-empty-test\project\Classes\HelloWorldScene.cpp)

3、写一个生成的python脚本,你不会写,没关系,我们会照猫画虎
   1)进入目录cocos2d-x-3.0rc0\tools\tolua,复制一份genbindings.py,命名为genbindings_myclass.py
   2)把生成目录制定到咱工程里去,打开genbindings_myclass.py把

?
1
output_dir = '%s/cocos/scripting/lua-bindings/auto' % project_root
 改成
?
1
output_dir = '%s/tests/lua-empty-test/project/Classes/auto' % project_root
  3)修改命令参数,把
?
1
2
3
4
5
6
7
cmd_args = { 'cocos2dx.ini' : ( 'cocos2d-x' , 'lua_cocos2dx_auto' ), \
                    'cocos2dx_extension.ini' : ( 'cocos2dx_extension' , 'lua_cocos2dx_extension_auto' ), \
                    'cocos2dx_ui.ini' : ( 'cocos2dx_ui' , 'lua_cocos2dx_ui_auto' ), \
                    'cocos2dx_studio.ini' : ( 'cocos2dx_studio' , 'lua_cocos2dx_studio_auto' ), \
                    'cocos2dx_spine.ini' : ( 'cocos2dx_spine' , 'lua_cocos2dx_spine_auto' ), \
                    'cocos2dx_physics.ini' : ( 'cocos2dx_physics' , 'lua_cocos2dx_physics_auto' ), \
                    }
    改成
?
1
cmd_args = { 'myclass.ini' : ( 'myclass' , 'lua_myclass_auto' ) }
    4)这时你可能问myclass.ini在哪啊,我们下来就写这个文件。原理一样,我还是照猫画虎,拿cocos2dx_spine.ini改的。
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
[myclass]
# the prefix to be added to the generated functions. You might or might not use this in your own
# templates
prefix = myclass
  
# create a target namespace (in javascript, this would create some code like the equiv. to `ns = ns || {}`)
# all classes will be embedded in that namespace
target_namespace =
  
android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.7/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.7/include
android_flags = -D_SIZE_T_DEFINED_ 
  
clang_headers = -I%(clangllvmdir)s/lib/clang/3.3/include 
clang_flags = -nostdinc -x c++ -std=c++11
  
cocos_headers = -I%(cocosdir)s/cocos -I%(cocosdir)s/cocos/2d -I%(cocosdir)s/cocos/base -I%(cocosdir)s/cocos/ui -I%(cocosdir)s/cocos/physics -I%(cocosdir)s/cocos/2d/platform -I%(cocosdir)s/cocos/2d/platform/android -I%(cocosdir)s/cocos/math/kazmath -I%(cocosdir)s/extensions -I%(cocosdir)s/external -I%(cocosdir)s/cocos/editor-support -I%(cocosdir)s
  
cocos_flags = -DANDROID -DCOCOS2D_JAVASCRIPT
  
cxxgenerator_headers =
  
# extra arguments for clang
extra_arguments = %(android_headers)s %(clang_headers)s %(cxxgenerator_headers)s %(cocos_headers)s %(android_flags)s %(clang_flags)s %(cocos_flags)s %(extra_flags)s 
  
# what headers to parse
headers = %(cocosdir)s/tests/lua-empty- test /project/Classes/HelloWorldScene.h
  
# what classes to produce code for. You can use regular expressions here. When testing the regular
# expression, it will be enclosed in "^$", like this: "^Menu*$".
classes = HelloWorld
  
# what should we skip? in the format ClassName::[function function]
# ClassName is a regular expression, but will be used like this: "^ClassName$" functions are also
# regular expressions, they will not be surrounded by "^$". If you want to skip a whole class, just
# add a single "*" as functions. See bellow for several examples. A special class name is "*", which
# will apply to all class names. This is a convenience wildcard to be able to skip similar named
# functions from all classes.
  
skip =
  
rename_functions =
  
rename_classes =
  
# for all class names, should we remove something when registering in the target VM?
remove_prefix =
  
# classes for which there will be no "parent" lookup
classes_have_no_parents =
  
# base classes which will be skipped when their sub-classes found them.
base_classes_to_skip = Ref ProcessBase
  
# classes that create no constructor
# Set is special and we will use a hand-written constructor
abstract_classes =
  
# Determining whether to use script object(js object) to control the lifecycle of native(cpp) object or the other way around. Supported values are 'yes' or 'no'.
script_control_cpp = no
    改的时候要注意这些行
?
1
2
3
4
5
6
7
[myclass]
prefix = myclass
target_namespace =
headers = %(cocosdir)s/tests/lua-empty- test /project/Classes/HelloWorldScene.h
classes = HelloWorld
skip =
abstract_classes =
4、下面要自动生成代码了,打开命令行工具,cd到cocos2d-x-3.0rc0\tools\tolua下,敲入
?
1
python genbindings_myclass.py
回车运行。如果前面没问题的话你会在cocos2d-x-3.0rc0\tests\lua-empty-test\project\Classes多了一个文件夹auto,然后把里面生成lua_myclass_auto.cpp和lua_myclass_auto.hpp加入拽如工程

5、把我们生成的个module在脚本引擎初始化的时候加入lua。
编辑AppDelegate.cpp,包含lua_myclass_auto.hpp头文件,在
?
1
LuaEngine* engine = LuaEngine::getInstance();
后面加入
?
1
register_all_myclass(engine->getLuaStack()->getLuaState());

6、编译运行。这样HelloWorld这个类就被导出到lua了。

测试------------------------------------------------
打开hello.lua,编辑local function main()这个函数
把前面改成
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
local function main()
    -- avoid memory leak
    collectgarbage ( "setpause" , 100)
    collectgarbage ( "setstepmul" , 5000)
 
    local hello = HelloWorld:create()
    local sceneGame = cc.Scene:create()
    sceneGame:addChild(hello)
    cc.Director:getInstance():runWithScene(sceneGame)
 
    if (1==1) then
        return
    end
……
……
转载自:http://www.cocos2d-x.org/wiki/Binding_Custom_Class_To_Lua_Runtime

How to bind a custom class to lua runtime


This document targets to show how to bind a custom cpp class to lua runtime. Not for details of luabinding.

Processes of all platforms are similar, to facilitate this, let's choose Mac runtime as example.

Generate source code for runtime

This assumes you have a cocos lua project in Cocos Code IDE named CocosLuaGame.

  • Source code of runtime is stored in <projectLocation>/frameworks/runtime-src, if this directory exist, skip next step.
  • Otherwise, you need generate source code for runtime by following steps:
    • Right click CocosLuaGame project
    • Cocos Tools->Add Native Codes Support...
    • click Generate in Create Native Source Wizard
    • Now the source code have been generated

Add CustomClass class in project

// CustomClass.h

#ifndef __CUSTOM__CLASS

#define __CUSTOM__CLASS

#include "cocos2d.h"

namespace cocos2d {
class CustomClass : public cocos2d::Ref
{
public:

    CustomClass();

    ~CustomClass();

    bool init();

    std::string helloMsg();

    CREATE_FUNC(CustomClass);
};
} //namespace cocos2d

#endif // __CUSTOM__CLASS

// CustomClass.cpp
#include "CustomClass.h"

USING_NS_CC;

CustomClass::CustomClass(){

}

CustomClass::~CustomClass(){

}

bool CustomClass::init(){
    return true;
}

std::string CustomClass::helloMsg() {
    return "Hello from CustomClass::sayHello";
}

open frameworks/runtime-src/proj.ios_mac/CocosLuaGame.xcodeproj, add CustomClass.h/CustomClass.cpp to cocos2d_libs.xcodeproj. Please check cocos2dx iOS on the bottom:

then you will see the new project structure:

add search path:

Add cocos2dx_custom.ini

open tools/tolua directory and add cocos2dx_custom.ini file:

content of this file is, please leave target_namespace blank, embed custom class in a namespace’s code auto-complete is not yet supported by Cocos Code IDE:

[cocos2dx_custom]
# the prefix to be added to the generated functions. You might or might not use this in your own
# templates
prefix = cocos2dx_custom

# create a target namespace (in javascript, this would create some code like the equiv. to `ns = ns || {}`)
# all classes will be embedded in that namespace
target_namespace =

android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.7/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.7/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.8/include
android_flags = -D_SIZE_T_DEFINED_ 

clang_headers = -I%(clangllvmdir)s/lib/clang/3.3/include 
clang_flags = -nostdinc -x c++ -std=c++11

cocos_headers = -I%(cocosdir)s/cocos -I%(cocosdir)s/my -I%(cocosdir)s/cocos/base -I%(cocosdir)s/cocos/platform/android
cocos_flags = -DANDROID

cxxgenerator_headers = 

# extra arguments for clang
extra_arguments = %(android_headers)s %(clang_headers)s %(cxxgenerator_headers)s %(cocos_headers)s %(android_flags)s %(clang_flags)s %(cocos_flags)s %(extra_flags)s 

# what headers to parse
headers = %(cocosdir)s/cocos/my/CustomClass.h

# what classes to produce code for. You can use regular expressions here. When testing the regular
# expression, it will be enclosed in "^$", like this: "^Menu*$".
classes = CustomClass.*

# what should we skip? in the format ClassName::[function function]
# ClassName is a regular expression, but will be used like this: "^ClassName$" functions are also
# regular expressions, they will not be surrounded by "^$". If you want to skip a whole class, just
# add a single "*" as functions. See bellow for several examples. A special class name is "*", which
# will apply to all class names. This is a convenience wildcard to be able to skip similar named
# functions from all classes.

skip = 

rename_functions = 

rename_classes = 

# for all class names, should we remove something when registering in the target VM?
remove_prefix = 

# classes for which there will be no "parent" lookup
classes_have_no_parents = 

# base classes which will be skipped when their sub-classes found them.
base_classes_to_skip = 

# classes that create no constructor
# Set is special and we will use a hand-written constructor
abstract_classes = 

# Determining whether to use script object(js object) to control the lifecycle of native(cpp) object or the other way around. Supported values are 'yes' or 'no'.
script_control_cpp = no

Change tools/tolua/genbindings.py

find cmd_args in tools/tolua/genbindings.py and add a line:

  'cocos2dx_custom.ini' : ('cocos2dx_custom', 'lua_cocos2dx_custom'), \

Run tools/tolua/genbindings.py

run tools/tolua/genbindings.py, then you would find lua_cocos2dx_custom.cpp and lua_cocos2dx_custom.h in cocos/scripting/lua-bindings/auto directory, and CustomClass.lua in cocos/scripting/lua-bindings/auto/api:

add .h/.cpp in Xcode project:

Register it to lua

open lua_cocos2dx_custom.h, that is a global function declare --> register_all_cocos2dx_custom(lua_State* tolua_S);

call this function before CustomClass is used, for example, in AppDelegate.cpp before run Lua entry file:

    ...
    #include "lua_cocos2dx_custom.hpp"
    ...

    // register custom function
    LuaStack* stack = engine->getLuaStack();
    auto state = stack->getLuaState();
    lua_getglobal(state, "_G");
    register_all_cocos2dx_custom(state);
    lua_pop(state, 1);

#if (COCOS2D_DEBUG>0)
    if (startRuntime())
        return true;
#endif

    engine->executeScriptFile(ConfigParser::getInstance()->getEntryFile().c_str());
    return true;        

Build runtime

In Cocos Code IDE:

  • Right click CocosLuaGame project
  • Cocos Tools->Build Runtime...
  • Select target platforms then build

Add CustomClass auto completion for Cocos Code IDE(1.0.1.beta or above)

zip CustomClass.lua to a zip file, such as CustomClass.zip by follow command:

zip CustomClass.zip CustomClass.lua

In Cocos Code IDE:

  • Right click CocosLuaGame project
  • Build Path->Configure Build Path...->Libraries->Add ZIPS...
  • Select the CustomClass.zip and OK

Using CustomClass in lua

Edit main.lua, using CustomClass where you want:

    local customClass = CustomClass:create()
    local msg = customClass:helloMsg()
    cclog("customClass's msg is : " .. msg)

Test

Run/Debug this project with new runtime named CocosLuaGame, you would see log in console:

customClass's msg is : Hello from CustomClass::sayHello


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值