学习工作项目中Lua和C++如何交互,从新建项目开始
# 一、环境搭建
# 一定要根据Cocos官方文档 (opens new window)中环境要求进行软件版本安装,避免出现各种环境导致的问题
本篇文章基于Cocos2dx-3.17版本:
- Python版本为2.7+(32位[1])
- NDK r16+
- Visual Studio 2015
安装完后,注意检查环境变量是否正确
# 二、项目创建
# 2.1 命令行新建项目
cocos new LuaProjTest -p com.zonst.test -l lua
1
# 2.2 打开项目解决方案,把LuaProjTest设为启动项,并开始调试
- 初次构建需要等一段时间,如果环境没错,一般不会出现其他问题
- 如果出现
v140、v142等版本等问题,可以右键“解决方案”->“重定解决方案目标” - 如出现“无法打开文件
xxx.lib"问题,大概率是软件环境不匹配 - 其他具体问题具体分析

# 2.3 在Classes下新建需要增加的类
创建完成后开始调试,看有无报错(具体LuaEngine使用,请查看文末参考资料)

# 三、使用genbindings脚本生成桥接文件
# 3.1 创建ini文件
进入项目引擎如下目录,复制一份已有的ini文件,并更名为 CUtils.ini 
打开此文件,需要修改的地方主要在高亮行:
[CUtils]
# the prefix to be added to the generated functions. You might or might not use this in your own
# templates
prefix = CUtils
# 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 = cc
# 此处是宏定义判断,若不需要,可以去除
macro_judgement = #if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM == CC_PLATFORM_TIZEN
android_headers =
android_flags = -target armv7-none-linux-androideabi -D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS -DANDROID -D__ANDROID_API__=14 -gcc-toolchain %(gcc_toolchain_dir)s --sysroot=%(androidndkdir)s/platforms/android-14/arch-arm -idirafter %(androidndkdir)s/sources/android/support/include -idirafter %(androidndkdir)s/sysroot/usr/include -idirafter %(androidndkdir)s/sysroot/usr/include/arm-linux-androideabi -idirafter %(clangllvmdir)s/lib64/clang/5.0/include -I%(androidndkdir)s/sources/cxx-stl/llvm-libc++/include
clang_headers =
clang_flags = -nostdinc -x c++ -std=c++11 -fsigned-char -U__SSE__
cocos_headers = -I%(cocosdir)s -I%(cocosdir)s/cocos -I%(cocosdir)s/cocos/platform/android -I%(cocosdir)s/external
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 = F:/SamerWorld/LuaProjTest/frameworks/runtime-src/Classes/CUtils.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 = CUtils
# 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 = AudioEngine::[setFinishCallback]
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 = AudioEngine AudioProfile
# 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
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
60
61
62
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
60
61
62
# 3.2 修改genbindings.py脚本

# 3.3 执行genbindings.py脚本&可能出现的报错解决方法
建议打开命令行窗口执行此脚本,方便看到报错信息
# 3.3.1 缺少yaml:
报错"ImportError: No module named yaml",这是因为未安装yaml模块,下载安装yaml模块即可:
http://pyyaml.org/download/pyyaml/PyYAML-3.10.win32-py2.7.exe (opens new window)
# 3.3.2 未安装Cheetah:
安装yaml后再运行genbindings.py,报错ImportError: No module named Cheetah.Template,原因是缺少了Cheetah库,下载安装即可
http://github.com/cheetahtemplate/cheetah/zipball/v2.4.2 (opens new window)
- 将下载完的zip文件解压到任意目录,例如
C:\Python27\Lib\cheetahtemplate-cheetah-7b1c2ad\ - 命令行依次执行以下命令
C:
cd \Python27\Lib\cheetahtemplate-cheetah-7b1c2ad>
python setup.py build
python setup.py install
1
2
3
4
2
3
4
# 3.3.3 Python版本不符
报错"LibclangError:[Error 193]%1不是有效的Win32.To provide a Config.set_library_path() or Config."
按照前面两步安装的yaml和Cheetah库都是win32版本的,出现这个错误是因为python不是win32版本,全部都用win32版本即可
# 3.4 项目导入桥接文件
# 3.4.1 如果上述步骤都成功了,在frameworks\cocos2d-x\cocos\scripting\lua-bindings\auto中会找到生成的C++的桥接文件,lua_CUtils_auto.cpp和lua_CUtils_auto.hpp

# 3.4.2 项目工程导入桥接文件

# 3.4.3 修改桥接文件
- 引入自定义类的头文件

- 如果自定义类中的方法传入了lua回调函数,比如此自定义类的
executeWithCb方法,需要修改桥接文件的转换代码(工具Bug)
# 四、lua脚本调用示例
# 五、参考资料
- 教你解决Cocos套件中Lua绑定C++出现的问题 (opens new window)
- Cocos3.x导出自定义类到Lua以及手动绑定要回调的函数 (opens new window)
- Cocos2d-x3.0如何绑定调用lua回调函数 (opens new window)
- Cocos2d-x下Lua调用自定义C++类和函数的最佳实践 (opens new window)