文档章节

CC3.2+Lua(8) ——Lua调用自定义C++类

0-1
 0-1
发布于 2014/10/29 10:04
字数 2177
阅读 2528
收藏 6

【唠叨】

    本节要讲的是如果将自己写的C++类注册进Lua环境,让Lua去调用自定义的C++类

    网上有很多都是用原始的tolua++工具来注册C++类的,我看了很多这样的教程,感觉操作起来十分麻烦,而且也很难看懂他们到底在讲什么。

    其实,在cocos2dx v3.2版本中,提供了bindings-generator脚本来封装toLua++的用法,从而节省了工作量。


【致谢】

    http://segmentfault.com/blog/hongliang/1190000000718145 (讲得非常好!)

    http://cn.cocos2d-x.org/article/index?type=code-ide&url=/doc/cocos-docs-master/manual/code-ide/binding-custom-class-to-lua/zh.md (官方文档)


【使用工具】

    Windows7 x64

    Cocos2dx v3.2

    Cocos Code IDE 1.0.1 (支持自定义类的智能提示功能)


    python 2.7.x(v3.2版本不一定要2.7.3,我用2.7.8也成功了的)

    NDK r9d ,解压并配置环境变量NDK_ROOT(v3.2版本不一定要r9b,我用r9d成功了的)

    pyyaml ,安装到 "Python的安装目录\Lib\site-packages"

        http://pyyaml.org/download/pyyaml/PyYAML-3.10.win32-py2.7.exe

    Cheetah ,并解压到 "Python的安装目录\Lib\site-packages"

        https://raw.github.com/dumganhar/my_old_cocos2d-x_backup/download/downloads/Cheetah.zip

    dos2unix ,windows下可能在执行脚本时有这个错误。

        解压到一某个目录下面, 并设置PATH环境变量的值指向bin目录下。

        http://waterlan.home.xs4all.nl/dos2unix/dos2unix-7.1-win32.zip




【绑定方法】

    以下介绍的是在 Windows7 + VS2013 + Cocos Code IDE

    并使用Cocos Code IDE创建的Lua项目,绑定方法。


1、将自定义的C++代码放在 frameworks\runtime-src\Classes 下

    当然放哪里是随意的,我喜欢放在Classes下。

wKioL1RL0zrCwXR9AAF0rHubdVQ695.jpg


2、添加自定义类的.ini文件

    在 frameworks\cocos2d-x\tools\tolua 中,复制一份该文件夹下cocos2dx.ini的配置信息,然后修改一些参数,改成我们自定义类的参数。

wKioL1RL1NvAEgUdAAAxRDlqd4k342.jpg

    以下列出需要修改的参数配置:

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
[custom_api]
  
# prefix会被添加到生成的函数.你也可以选择不添加这个到你的模板
prefix = custom_api
  
# 所有的类都会嵌入到这个命名空间
target_namespace = my
  
# 类所在的路径,如果有多个,用空格隔开
headers = %(cocosdir)s/../runtime-src/Classes/PanZoomLayer.h
  
# 需要注册的类,如果有多个,用空格隔开
classes = PanZoomLayer
  
# 不提供给Lua的public成员函数
skip = PanZoomLayer::[onTouchesBegan onTouchesMoved onTouchesEnded init onEnter onExit update]
  
# 这些全空就好了
rename_functions =
rename_classes = 
remove_prefix = 
classes_have_no_parents = 
base_classes_to_skip =
abstract_classes = 
script_control_cpp = no


3、genbindings.py 添加自定义的配置.ini

    在 frameworks\cocos2d-x\tools\tolua 的 genbindings.py 中的129行找到 cmd_args

    将我们自定义的 custom_api.ini 添加进去,并注释掉其他.ini(这些已经不需要重新生成)

wKioL1RL2RGx9zP1AAMRjTrGUh4452.jpg


4、运行 genbindings.py 脚本

    在终端运行 genbindings.py 脚本。

    在这里,我是直接写了一个批处理文件 .bat 。

    注意:只要需要用到的工具都下载,安装,配置好了,一般就能生成成功。

            生成失败的,基本都是因为工具没有配置好。

wKiom1RL2WPAnAYnAAD5jo7zWb8151.jpg


    生成成功后,在 frameworks\cocos2d-x\cocos\scripting\lua-bindings\auto 中会找到我们生成的C++的桥接文件, lua_custom_api_auto.cpplua_custom_api_auto.hpp

wKioL1RL2y6DVRX7AAB3H2ztpRw355.jpg


    其中 lua_custom_api_auto.hpp 中的 register_all_custom_api 就是我们用来将PanZoomLayer类注册到Lua环境中的关键函数。

wKiom1RL3CvQsTBNAAFpA5UFDjQ936.jpg


    以及在 frameworks\cocos2d-x\cocos\scripting\lua-bindings\auto\api 中也能够找到我们提供给Lua调用的接口文件。

wKiom1RL23LiE_2EAADt_Dl4paM431.jpg


5、编译注册到Lua

    注册自定义类的函数在我们的 lua_custom_api_auto.hpp 中可以看到。

        register_all_custom_api(lua_State* tolua_S)

wKiom1RL3CvQsTBNAAFpA5UFDjQ936.jpg


    使用 VS2013 打开 frameworks\runtime-src\proj.win32 下的工程。

    (1)将自定义的类 PanZoomLayer 添加到项目工程的Classes下。

wKiom1RL3c6yZ4PEAAB3OlLbZhk958.jpg

    (2)将 lua_custom_api_auto.cpp、lua_custom_api_auto.hpp 添加到工程liblua的auto下。

wKiom1RL3qDikRCvAAG_ncnZkvQ661.jpg

    (3)添加lualib工程的文件搜索路径。

        将 $(EngineRoot)../runtime-src/Classes 路径加进去。

wKioL1RL32rhaAU8AAE8tMBgTpw591.jpg

    (4)编辑 frameworks\runtime-src\Classes 下的入口类 AppDelegate.cpp

        > 添加:lua_custom_api_auto.hpp 头文件

wKiom1RL3Lug2Np1AAAqi0a-IYQ249.jpg

        > 注册:register_all_custom_api(state)

        > 注意:register_all_custom_api 的上下两句话,必须加上!

wKioL1RL3Q2QDNclAAHPrYX_6BI408.jpg

    

    (5)编译运行整个项目,完成C++类的注册到Lua。

        然后就可以再Lua中愉快的使用自定义的类了!




【开启智能提示】

    虽然我们将我们自定义的C++类注册到了Lua中调用,但是在Cocos Code IDE中却没有我们自定义类的智能提示。

    我们需要修改一些配置,让Cocos Code IDE加上对我们自定义类的智能提示


1、Cocos2dx引擎中的智能提示

    首先我们来看一下Cocos Code IDE中cocos2dx引擎的智能提示是怎么搞的。

    随便找个 cc.Label 把!

    我们按住键盘的 ctrl 键,然后点击 cc Label,就会跳转到声明它们的地方。

wKiom1RL4vGjjv10AAAi5Dt7P4A782.jpg

    文件跳转到了如下两幅图的地方:

wKioL1RL4-KhMI4XAAFP955pFxc307.jpg


wKioL1RL4-OihcZkAAGNcLJuOOY308.jpg


    可能看到以上两幅图,你就明白应该怎么给我们自定义的C++类加上智能提示了吧?


    我们先找到以下文件路径:(可能每个人的不一样)

    \CocosCodeIDE\configuration\org.eclipse.osgi\bundles\61\1\.cp\resource\cocos2dx-3.2

    可以发现该路径下有一个 api.zip 这个压缩包。

    我们将其 api.zip 解压出来看看里面都是什么东西。wKiom1RL5I7QTUXfAAE4J2kdwJU349.jpg

wKioL1RL5prSbATiAAF56z9JNAI653.jpg


wKiom1RL9vuT2T9LAAJ2fGK5-kU348.jpg


    可以发现里面全是cocos2dx的C++类提供给Lua的接口声明。

    这些也就是IDE中智能提示的原因。


2、添加自定义类的智能提示(方式一)

    我们仿照 api.zip 中的 cc.lua 和 label.lua 来写一个自定义类的接口声明。

        > my.lua           :声明命名空间

        > PanZoomLayer.lua :声明自定义类。(这个在使用脚本绑定时,自动生成)

    其中 PanZoomLayer.lua 在使用 genbindings.py 脚本时,就自动生成了的。

        就在 frameworks\cocos2d-x\cocos\scripting\lua-bindings\auto\api 中。

    那么,我们再写一个 my.lua ,也放在这个目录下好了。

    其中,my.lua 代码如下:

1
2
3
4
5
6
7
8
9
--------------------------------
-- @module my
  
--------------------------------------------------------
-- the my PanZoomLayer
-- @field [parent=#my] PanZoomLayer#PanZoomLayer PanZoomLayer preloaded module
  
  
return nil


wKioL1RL947iMVEQAAEoZxR9ge8316.jpg


    PanZoomLayer.lua 代码如下:

wKioL1RL6cCiCX9WAAM6bAzCK7Y304.jpg


    然后我们将 my.lua 和 PanZoomLayer.lua 一并压缩到 myapi.zip 中

    就放在 \frameworks\cocos2d-x\cocos\scripting\lua-bindings\auto\api 中好了。

wKioL1RL6wPiJgirAAEhY5DYprw732.jpg


    然后我们打开Cocos Code IDE的工程项目,配置属性。

        Lua->Build Path->Libraries->Add External Zips

    将我们的 myapi.zip 压缩包添加进去,点击“确定”。

wKiom1RL6y6whGwdAAL9na5GZdw128.jpg


    这样,就可以在 Cocos Code IDE 中愉快的玩我们自定义的类了。

    有智能提示,就是爽啊!!!i_f07.gif

wKioL1RL7FrhojIFAABaW9-L54M677.jpg

wKiom1RL7AiDort9AACENIlt5Ec002.jpg

wKioL1RL7KLjVoFUAAHqxAbDB40728.jpg


3、添加智能提示(方式二)

    通过上面的方式一的方法虽然可以有智能提示,可是后来我发现定义的命名空间 my 却无法识别。这样的结果将导致创建的 my.PanZoomLayer:create() 赋值给 self 的成员 self.pzLayer 后,继续使用 self.pzLayer 时,对应的函数又无法提示了。

wKiom1RMtE6xkHlyAABfA0aiUEs010.jpg

    所以这里我们通过修改官方智能提示包 api.zip ,来达到更加的智能提示的效果。

    操作方法和方式一类似,我们先将官方的提示包 api.zip 解压出来,最好将其备份一份。

    文件在:

    \Cocos Code IDE\configuration\org.eclipse.osgi\bundles\61\1\.cp\resource\cocos2dx-3.2

wKioL1RMtUmSCXySAAEYK8cc_HA675.jpg


    然后我们将我们自定义提示包 my.luaPanZoomLayer.lua 放入 api 文件夹中。

wKiom1RMtkTQSQsKAAJeXFL4uHQ687.jpg


    然后在 api 文件夹中找到 global.lua 这个全局声明文件。

    将我们自定义的命名空间 my 声明进去。

1
2
-- the my module
-- @field [parent=#global] my#my my preloaded module


wKioL1RMteOzU_PZAAObQErZ1ys759.jpg


    保存关闭,将 api 文件夹压缩成 api.zip 包。

wKioL1RMtu7xnSPPAADALEjJJDI186.jpg

    

    然后刷新我们的项目工程,然后再来试试我们自定义类的智能提示效果。

    可以发现,自定义的类的智能提示已经和 官方的智能提示功能 完全一致了。

    又可以愉快的玩耍啦!!!i_f28.gif

wKiom1RMtuugmiVrAAJ-31JEBW4104.jpg




【遇到的问题】


1、脚本生成出错

wKiom1RLzk7A7N1lAANtk3-0x9o550.jpg

wKioL1RLzqDy_XmDAALksUIjK3g521.jpg

    

    这些出错都是由于没有配置 pyyaml、Cheetah、dos2unix 引起的,都下过来配置一下即可。


2、编译到Android手机出错

    上面的配置完成后IOS的部分是可以正常运行的,但是这个时候编译android时不通过的。

    因为 AppDelegate.cpp 里面调用的 register_all_MyClass(L) 方法在android不存在,android的项目里并没有配置去编译对应的 PanZoomLayer.cpp 文件和后续生成的 lua_custom_api_auto.cpp。

    所以需要在android端配置Android.mk文件,让项目编译时去编译这两个C++文件才行。


    (1)首先配置JNI下面的Android.mk文件,让JNI部分编译时去编译PanZoomLayer.cpp:

        编辑 frameworks/runtime-src/proj.android/jni/Android.mk

        在 LOCAL_SRC_FILES 参数的后面添加:(注意后面的 \ ,仅最后一行不加斜杠)

            ../../Classes/PanZoomLayer.cpp

wKiom1RL-RKiDEywAAH-iwiWIIY738.jpg


        在 LOCAL_C_INCLUDES 参数的后面添加:(注意后面的 ,仅最后一行不加斜杠

            $(LOCAL_PATH)/../../Classes

wKioL1RL-XvyZNt9AABZE6y2eYQ966.jpg


    (2)然后配置 frameworks/cocos2d-x/cocos/scripting/lua-bindings/Android.mk文件。

        在 LOCAL_SRC_FILES 参数的后面添加:(注意后面的 ,仅最后一行不加斜杠

            auto/lua_custom_api_auto.cpp

wKiom1RL-TyA_qxTAAHW36-i5xM024.jpg


        在 LOCAL_C_INCLUDES 参数的后面添加:(注意后面的 ,仅最后一行不加斜杠

            $(LOCAL_PATH)/../../../../runtime-src/Classes

wKioL1RL-ZyS6JLUAAGIxbrx4oo396.jpg


    (3)然后 Build-Runtime,将项目在Android端编译一下。

wKiom1RL-YTCkK43AAE9zSpAmfo656.jpg


    (4)若编译成功,就可以在Android手机上测试了!




本文转载自:http://shahdza.blog.51cto.com/2410787/1568051

0-1

0-1

粉丝 93
博文 268
码字总数 145989
作品 0
福州
程序员
私信 提问
FFLIB之FFLUA——C++嵌入Lua&扩展Lua利器

摘要: 在使用C++做服务器开发中,经常会使用到脚本技术,Lua是最优秀的嵌入式脚本之一。Lua的轻量、小巧、概念之简单,都使他变得越来越受欢迎。本人也使用过python做嵌入式脚本,二者各有特...

知然
2013/01/27
0
0
用LuaBridge为Lua绑定C/C++对象

最近为了总结Lua绑定C/C++对象的各种方法、第三方库和原理,学习了LuaBridge库为Lua绑定C/C++对象,下面是学习笔记,实质是对该库的Reference Manual基本上翻译了一遍,学习过程中测试代码,...

shezjl
2015/10/26
219
0
[架构设计]反向(或者后向)插件系统设计

反向(或者后向)插件系统与正向(或者前向)插件系统是一对概念相对的设计模式。正向插件系统是指系统架构的时候预先定义好一系列用于某种特定目的的函数族,然后通过共享库的形式封装不同的...

梁欢
2014/06/25
387
0
luabind 0.9.1版本尝试

luabind 0.9.1版本尝试 http://www.rasterbar.com/products/luabind 1. 编译luabind 0.9.1 linux版本 编译luabind需要bjam binary。 直接copy boost/1.37.0目录中编译好的bjam binary到~/bin......

zero-li
2014/01/14
368
0
cocos2d-lua绑定C++自定义类(自动+手动绑定回调函数)

1.自定义C++类 将文件保存在frameworks/runtime-src/Classes/目录下,然后编写对应的.ini文件(在frameworks/cocos2d-x/tools/tolua/目录),然后修改genbindings.py(同目录)文件141行附近,将...

Valiancer
2017/08/24
0
0

没有更多内容

加载失败,请刷新页面

加载更多

使用CSS自定义属性构建骨架屏

写在前面 几天前看到薄荷前端团队分享的《前端骨架屏方案小结》,突然回想起一年前看到的max bock写的《Building Skeleton Screens with CSS Custom Properties》,翻译整理写下出此文,分享...

前端老手
昨天
4
0
Docker常用命令小记

除了基本的<font color="blue">docker pull</font>、<font color="blue">docker image</font>、<font color="blue">docker ps</font>,还有一些命令及参数也很重要,在此记录下来避免遗忘。 ......

程序员欣宸
昨天
4
0
MAT使用-jvm内存溢出问题分析定位

1.MAT简介: MAT 全称 Eclipse Memory Analysis Tools 是一个分析 Java堆数据的专业工具,可以计算出内存中对象的实例数量、占用空间大小、引用关系等,看看是谁阻止了垃圾收集器的回收工作,...

xiaomin0322
昨天
4
0
内网和外网之间的通信(端口映射原理)

首先解释一下“内网”与“外网”的概念: 内网:即所说的局域网,比如学校的局域网,局域网内每台计算机的IP地址在本局域网内具有互异性,是不可重复的。但两个局域网内的内网IP可以有相同的...

Jack088
昨天
6
0
3.深入jvm内核-原理、诊断与优化-4. GC算法和种类

一、GC算法和种类 GC的概念 GC算法 引用计数法 标记清除 标记压缩 复制算法 可触及性 Stop-The-World GC的对象是堆空间和永久区 引用计数法 老牌垃圾回收算法 通过引用计算来回收垃圾 使用者...

hexiaoming123
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部