Quick-Cocos2dx-Community lua绑定,lua调用C++ 类
http://www.52php.cn/article/p-csyjushk-rm.html
这里有篇文章,看三和四。
按上面操作,文件都不缺少的,可以直接看 2. 和 3 . 记住:player3 来打开项目, 的类格式化后,放到他的源代码路径下面, 解释生成的lua 也要放到 api下面 player3 重新生成就可以了
player3 最后打开可能会出现, a nil value。
其实,我们用cocos2d-x-3.10,
D:cocossetupCocos2d-xcocos2d-x-3.10toolstolua genbindings.py **.ini 来转换成 lua能够调用的 类。
其实就是通过D:cocossetupCocos2d-xcocos2d-x-3.10toolstolua下提供:README.mdown.的说明来配置,最后生成lua api函数。——这里不妨称这一套东西为c++ 转成 lua 的 解释器或者解释工具,转换工具也成。
我的环境: win 7 64 位,Sublime Text 3,Quick-Cocos2dx-Community3.6(桌面快捷方式player3) vs 2013 Quick-Cocos2dx-Community 3.6 我没有转换成功,就用 cocos2d-x-3.10 转换,成功了 ======================================================== 以上才只是编译环境简单说明: Quick-Cocos2dx-Community 最好,现在这个下面试试, 我的是在 G:GameQuick-Cocos2dx-Communitytoolstolua 下面,按住shift + 右键点击选择 “在此处打开命令窗口”直接运行 python genbindings.py。 试试你的Quick-Cocos2dx-Community 能不能转换。
如果不行,也没有关系,这个时候,需要cocos2d-x 引擎来处理, 我的是cocos2d-x-3.10。 1. 把自己的类,.h .cpp 放到G:ademoframeworksruntime-srcClasses 这个下面 “runtime-srcClasses”, 这里的工程是G:下的ademo, (名字有点怪, demo 前面加个a 是便于player3 打开项目是 目录 在最上面。)
接下来是cocos2d-x-3.10解压安装目录下 D:cocossetupCocos2d-xcocos2d-x-3.10toolstolua cocos2dx.ini ,genbindings.py 各复制一份 修改名称
修改下面的配置 :Pet.ini Pet.py
[Pet] prefix = Pet 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 -U __SSE__ cocos_headers = -I%(cocosdir)s/cocos -I%(cocosdir)s/cocos/editor-support -I%(cocosdir)s/cocos/platform/android cocos_flags = -DANDROID cxxgenerator_headers = 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/scripting/lua-bindings/auto/Pet.h #headers = G:/aatestlua/frameworks/runtime-src/Classes/Pet.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 = Pet # 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 注意:headers = %(cocosdir)s/cocos/scripting/lua-bindings/auto/Pet.h 我使用绝对路径没有成功。 我就顺便把自己的类Pet.h 放到成才 lua 格式c++ 类同一目录下(runtime-srcClasses自己的c++类)。
%(cocosdir)s/cocos/scripting/lua-bindings/auto/ 就是这个目录
下面看Pet.py 这个里面 改的地方不多:
try: tolua_root = '%s/tools/tolua' % project_root output_dir = '%s/cocos/scripting/lua-bindings/auto' % project_root cmd_args = { #'cocos2dx.ini' : ('cocos2d-x','lua_cocos2dx_auto'), 'Pet.ini' : ('Pet','lua_pet_auto'), #'cocos2dx_assetsmanager.ini' : ('cocos2dx_assetsmanager','lua_cocos2dx_assetsmanager_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'), #'cocos2dx_experimental_video.ini' : ('cocos2dx_experimental_video','lua_cocos2dx_experimental_video_auto'), #'cocos2dx_experimental.ini' : ('cocos2dx_experimental','lua_cocos2dx_experimental_auto'), #'cocos2dx_controller.ini' : ('cocos2dx_controller','lua_cocos2dx_controller_auto'), #'cocos2dx_cocosbuilder.ini': ('cocos2dx_cocosbuilder','lua_cocos2dx_cocosbuilder_auto'), #'cocos2dx_cocosdenshion.ini': ('cocos2dx_cocosdenshion','lua_cocos2dx_cocosdenshion_auto'), #'cocos2dx_3d.ini': ('cocos2dx_3d','lua_cocos2dx_3d_auto'), #'cocos2dx_audioengine.ini': ('cocos2dx_audioengine','lua_cocos2dx_audioengine_auto'), #'cocos2dx_csloader.ini' : ('cocos2dx_csloader','lua_cocos2dx_csloader_auto'), } target = 'lua' generator_py = '%s/generator.py' % cxx_generator_root for key in cmd_args.keys(): args = 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) if platform == 'win32': with _pushd(output_dir): _run_cmd('dos2unix *') 只需要 在cmd_args = { }中 把不需要的 注释掉,这样 解释起来 快点
tolua_root = '%s/tools/tolua' % project_root 这里的两个目录,上面的是 我修改 .ini 和 .py 的目录,下面的是 生成的目录, 我们需要 解释的类放的目录, 上面有提到这个目录 好了贴一下这个配置,以免有遗漏的地方
#!/usr/bin/python # This script is used to generate luabinding glue codes. # Android ndk version must be ndk-r9b. import sys import os,os.path import shutil import ConfigParser import subprocess import re from contextlib import contextmanager def _check_ndk_root_env(): ''' Checking the environment NDK_ROOT,which will be used for building ''' try: NDK_ROOT = os.environ['NDK_ROOT'] except Exception: print "NDK_ROOT not defined. Please define NDK_ROOT in your environment." sys.exit(1) return NDK_ROOT def _check_python_bin_env(): ''' Checking the environment PYTHON_BIN,which will be used for building ''' try: PYTHON_BIN = os.environ['PYTHON_BIN'] except Exception: print "PYTHON_BIN not defined,use current python." PYTHON_BIN = sys.executable return PYTHON_BIN class CmdError(Exception): pass @contextmanager def _pushd(newDir): previousDir = os.getcwd() os.chdir(newDir) yield os.chdir(previousDir) def _run_cmd(command): ret = subprocess.call(command,shell=True) if ret != 0: message = "Error running command" raise CmdError(message) def main(): cur_platform= '??' llvm_path = '??' ndk_root = _check_ndk_root_env() # del the " in the path ndk_root = re.sub(r""","",ndk_root) python_bin = _check_python_bin_env() platform = sys.platform if platform == 'win32': cur_platform = 'windows' elif platform == 'darwin': cur_platform = platform elif 'linux' in platform: cur_platform = 'linux' else: print 'Your platform is not supported!' sys.exit(1) if platform == 'win32': x86_llvm_path = os.path.abspath(os.path.join(ndk_root,'toolchains/llvm-3.3/prebuilt','%s' % cur_platform)) if not os.path.exists(x86_llvm_path): x86_llvm_path = os.path.abspath(os.path.join(ndk_root,'toolchains/llvm-3.4/prebuilt','%s' % cur_platform)) else: x86_llvm_path = os.path.abspath(os.path.join(ndk_root,'%s-%s' % (cur_platform,'x86'))) if not os.path.exists(x86_llvm_path): x86_llvm_path = os.path.abspath(os.path.join(ndk_root,'x86'))) x64_llvm_path = os.path.abspath(os.path.join(ndk_root,'x86_64'))) if not os.path.exists(x64_llvm_path): x64_llvm_path = os.path.abspath(os.path.join(ndk_root,'x86_64'))) if os.path.isdir(x86_llvm_path): llvm_path = x86_llvm_path elif os.path.isdir(x64_llvm_path): llvm_path = x64_llvm_path else: print 'llvm toolchain not found!' print 'path: %s or path: %s are not valid! ' % (x86_llvm_path,x64_llvm_path) sys.exit(1) project_root = os.path.abspath(os.path.join(os.path.dirname(__file__),'..','..')) cocos_root = os.path.abspath(os.path.join(project_root,'')) cxx_generator_root = os.path.abspath(os.path.join(project_root,'tools/bindings-generator')) # save config to file config = ConfigParser.ConfigParser() config.set('DEFAULT','androidndkdir',ndk_root) config.set('DEFAULT','clangllvmdir',llvm_path) config.set('DEFAULT','cocosdir',cocos_root) config.set('DEFAULT','cxxgeneratordir',cxx_generator_root) config.set('DEFAULT','extra_flags','') # To fix parse error on windows,we must difine __WCHAR_MAX__ and undefine __MINGW32__ . if platform == 'win32': config.set('DEFAULT','-D__WCHAR_MAX__=0x7fffffff -U__MINGW32__') conf_ini_file = os.path.abspath(os.path.join(os.path.dirname(__file__),'userconf.ini')) print 'generating userconf.ini...' with open(conf_ini_file,'w') as configfile: config.write(configfile) # set proper environment variables if 'linux' in platform or platform == 'darwin': os.putenv('LD_LIBRARY_PATH','%s/libclang' % cxx_generator_root) if platform == 'win32': path_env = os.environ['PATH'] os.putenv('PATH',r'%s;%slibclang;%stoolswin32;' % (path_env,cxx_generator_root,cxx_generator_root)) try: tolua_root = '%s/tools/tolua' % project_root output_dir = '%s/cocos/scripting/lua-bindings/auto' % project_root cmd_args = { #'cocos2dx.ini' : ('cocos2d-x',args[1]) _run_cmd(command) if platform == 'win32': with _pushd(output_dir): _run_cmd('dos2unix *') print '---------------------------------' print 'Generating lua bindings succeeds.' print '---------------------------------' except Exception as e: if e.__class__.__name__ == 'CmdError': print '---------------------------------' print 'Generating lua bindings fails.' print '---------------------------------' sys.exit(1) else: raise # -------------- main -------------- if __name__ == '__main__': main() 接下来, 开始 按住 shift键 右键 单击当前 文件夹 空白 选中 “当前窗口打开命令窗口”
输入: python Pet.py 成功是 会出现 lua binding succeeds. 接下来 会出现 四个文件, D:cocossetupCocos2d-xcocos2d-x-3.10cocosscriptinglua-bindingsauto lua格式的c++ 类 lua_pet_auto.hpp lua_pet_auto.cpp D:cocossetupCocos2d-xcocos2d-x-3.10cocosscriptinglua-bindingsautoapi lua_pet_auto_api.lua Pet.lua 这里需要注意:有的 没有生成Pet.lua 是因为你的 .ini 下面 class=Pet 没有指定要生成的类。
2. 需要用 vs 2013 来检验 ,调用 。 本文开头的链接 将的很清楚,这里就不啰嗦了。
可能到最后,vs 2013 打开运行 没有问题,但是 lua 直接用player3 打开工程 会有问题******(a nil value). function MainScene:ctor() cc.ui.UILabel.new({ UILabelType = 2,text = "Hello,World",size = 64}) :align(display.CENTER,display.cx,display.cy) :addTo(self) pet = Pet:new() print(strhello); strhello = pet:getTestText(); local mPet = pet:addTo(self) print("===============调用成功===================") cc.ui.UILabel.new({ UILabelType = 2,text = strhello,size = 32}) :align(display.CENTER,display.cy + 100) :addTo(self) end你要确保你的vs工程下面libluacocos2d -auto :lua_pet_auto.cpp 和lua_pet_auto.hpp 存在。 这个我是放在player3 源代码 路径下的:G:GameQuick-Cocos2dx-Communitycocosscriptinglua-bindingsauto 可以直接 右键属性, c++ 头文件路径导入 绝对路径G:ademoframeworksruntime-srcClasses Pet.h Pet.cpp 这里配置成功后, 后面需要打开的另一个工程就不需要配置了。
你的工程 下(这里我的是ademo) 下面 右键属性G:GameQuick-Cocos2dx-Communitycocosscriptinglua-bindingsauto lua_pet_auto.cpp 和lua_pet_auto.hpp 存在 G:GameQuick-Cocos2dx-Communitycocosscriptinglua-bindingsautoapi lua_pet_auto_api.lua 和Pet.lua存在 就是 把cocos2d-x-3.10 下成才的东西player3 在放置一下,因为你是用player3吗,对吧!
注意:你用的是player3 ,但此时,为什么没有成功,这是为什么呢? 嘿嘿。
虽说你的 lua_pet_auto.cpp 和lua_pet_auto.hpp 也放到player3 的资源目录下啦(G:GameQuick-Cocos2dx-Communitycocosscriptinglua-bindingsauto) lua_pet_auto_api.lua 和Pet.lua 也在G:GameQuick-Cocos2dx-Communitycocosscriptinglua-bindingsautoapi 下了。
为什么呢? —— vs 打开工程 重新构建 ,build all 。 把所有的东西 整合。 因为 你用的player3 ,是编译生成好的 。
3. 那好,我们来操作.... G:GameQuick-Cocos2dx-Communityquickplayer 找到 proj.win32 vs 打开 解决方案player.sln 重新 生成解决方案。
返回到上级目录 :G:GameQuick-Cocos2dx-Communityquickplayer win32 文件夹 ,就是 你的player3(桌面没有的 ,右键桌面快捷方式)
重新生成解决方案后,打开看看,是不是成功了。
注意:vs 打开 解决方案player.sln 下 项目libluacocos2d 和你工程的 应该是一样的, 这也是上面我们提到的你会用到的。 只需要player3 工程 下 class 右键添加 G:GameQuick-Cocos2dx-CommunityquickplayerClassesPet.h Pet.cpp 这里是从你的工程下 “frameworksruntime-srcClasses” 下哪来的 这也是 为什么 开始 让你 Quick-Cocos2dx-Community 下试试 能不能运行成功的原因, 成功了,就不需要cocos2d-x-3.10 来生成
直接 在G:GameQuick-Cocos2dx-Communitytoolstolua 生成, 后面不要 复制过来复制过去了。
好了完了。
补充: http://www.cocoachina.com/bbs/read.php?tid=200145 vs 调用 自己的类注意事项: bool AppDelegate::applicationDidFinishLaunching() { LuaEngine * lua_engine = LuaEngine::getInstance(); ScriptEngineManager::getInstance()->setScriptEngine(lua_engine); lua_State* luaState = lua_engine->getLuaStack()->getLuaState(); if (L) { lua_getglobal(luaState,"_G"); register_all_Pet(luaState); lua_settop(luaState,0); } //register custom function //LuaStack* stack = engine->getLuaStack(); //register_custom_function(stack->getLuaState()); //FileUtils::getInstance()->setResourceEncryptKeyAndSign("test","XXTEA"); } 这里补上资源:http://download.csdn.net/detail/bible521125/9539325 或者 官方文档: 以上仅供参考,欢迎留言指正错误! 附上邮箱:545625405@qq.com (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |