上一章中將fairyGUI集成到C++工程,由於本人使用的是cocoslua,還需要將C++的綁定到lua中使用,本章記錄一下過程,由於是過了一段時間,有些步驟忘記了,大概記錄一下,諸位大大做個臨時參考吧
1 打開\cocos2d-x-3.17.2\tools\tolua文件夾,創建一個py腳本,FairyGUIgenbindings.py.仿照genbingings.py寫入代碼:
1 #!/usr/bin/python 2 3 # This script is used to generate luabinding glue codes. 4 # Android ndk version must be ndk-r9b. 5 6 7 import sys 8 import os, os.path 9 import shutil 10 import ConfigParser 11 import subprocess 12 import re 13 from contextlib import contextmanager 14 15 16 def _check_ndk_root_env(): 17 ''' Checking the environment NDK_ROOT, which will be used for building 18 ''' 19 20 try: 21 NDK_ROOT = os.environ['NDK_ROOT'] 22 except Exception: 23 print "NDK_ROOT not defined. Please define NDK_ROOT in your environment." 24 sys.exit(1) 25 26 return NDK_ROOT 27 28 def _check_python_bin_env(): 29 ''' Checking the environment PYTHON_BIN, which will be used for building 30 ''' 31 32 try: 33 PYTHON_BIN = os.environ['PYTHON_BIN'] 34 except Exception: 35 print "PYTHON_BIN not defined, use current python." 36 PYTHON_BIN = sys.executable 37 38 return PYTHON_BIN 39 40 41 class CmdError(Exception): 42 pass 43 44 45 @contextmanager 46 def _pushd(newDir): 47 previousDir = os.getcwd() 48 os.chdir(newDir) 49 yield 50 os.chdir(previousDir) 51 52 def _run_cmd(command): 53 ret = subprocess.call(command, shell=True) 54 if ret != 0: 55 message = "Error running command" 56 raise CmdError(message) 57 58 def main(): 59 60 cur_platform= '??' 61 llvm_path = '??' 62 ndk_root = _check_ndk_root_env() 63 # del the " in the path 64 ndk_root = re.sub(r"\"", "", ndk_root) 65 python_bin = _check_python_bin_env() 66 67 platform = sys.platform 68 if platform == 'win32': 69 cur_platform = 'windows' 70 elif platform == 'darwin': 71 cur_platform = platform 72 elif 'linux' in platform: 73 cur_platform = 'linux' 74 else: 75 print 'Your platform is not supported!' 76 sys.exit(1) 77 78 x86_llvm_path = "" 79 x64_llvm_path = os.path.abspath(os.path.join(ndk_root, 'toolchains/llvm/prebuilt', '%s-%s' % (cur_platform, 'x86_64'))) 80 if not os.path.exists(x64_llvm_path): 81 x86_llvm_path = os.path.abspath(os.path.join(ndk_root, 'toolchains/llvm/prebuilt', '%s' % (cur_platform))) 82 if not os.path.exists(x86_llvm_path): 83 x86_llvm_path = os.path.abspath(os.path.join(ndk_root, 'toolchains/llvm/prebuilt', '%s-%s' % (cur_platform, 'x86'))) 84 85 if os.path.isdir(x64_llvm_path): 86 llvm_path = x64_llvm_path 87 elif os.path.isdir(x86_llvm_path): 88 llvm_path = x86_llvm_path 89 else: 90 print 'llvm toolchain not found!' 91 print 'path: %s or path: %s are not valid! ' % (x86_llvm_path, x64_llvm_path) 92 sys.exit(1) 93 94 x86_gcc_toolchain_path = "" 95 x64_gcc_toolchain_path = os.path.abspath(os.path.join(ndk_root, 'toolchains/arm-linux-androideabi-4.9/prebuilt', '%s-%s' % (cur_platform, 'x86_64'))) 96 if not os.path.exists(x64_gcc_toolchain_path): 97 x86_gcc_toolchain_path = os.path.abspath(os.path.join(ndk_root, 'toolchains/arm-linux-androideabi-4.9/prebuilt', '%s' % (cur_platform))) 98 if not os.path.exists(x86_gcc_toolchain_path): 99 x86_gcc_toolchain_path = os.path.abspath(os.path.join(ndk_root, 'toolchains/arm-linux-androideabi-4.9/prebuilt', '%s-%s' % (cur_platform, 'x86'))) 100 101 if os.path.isdir(x64_gcc_toolchain_path): 102 gcc_toolchain_path = x64_gcc_toolchain_path 103 elif os.path.isdir(x86_gcc_toolchain_path): 104 gcc_toolchain_path = x86_gcc_toolchain_path 105 else: 106 print 'gcc toolchain not found!' 107 print 'path: %s or path: %s are not valid! ' % (x64_gcc_toolchain_path, x86_gcc_toolchain_path) 108 sys.exit(1) 109 110 111 project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..')) 112 cocos_root = os.path.abspath(os.path.join(project_root, '')) 113 cxx_generator_root = os.path.abspath(os.path.join(project_root, 'tools/bindings-generator')) 114 115 # save config to file 116 config = ConfigParser.ConfigParser() 117 config.set('DEFAULT', 'androidndkdir', ndk_root) 118 config.set('DEFAULT', 'clangllvmdir', llvm_path) 119 config.set('DEFAULT', 'gcc_toolchain_dir', gcc_toolchain_path) 120 config.set('DEFAULT', 'cocosdir', cocos_root) 121 config.set('DEFAULT', 'cxxgeneratordir', cxx_generator_root) 122 config.set('DEFAULT', 'extra_flags', '') 123 124 conf_ini_file = os.path.abspath(os.path.join(os.path.dirname(__file__), 'userconf.ini')) 125 126 print 'generating userconf.ini...' 127 with open(conf_ini_file, 'w') as configfile: 128 config.write(configfile) 129 130 131 # set proper environment variables 132 if 'linux' in platform or platform == 'darwin': 133 os.putenv('LD_LIBRARY_PATH', '%s/libclang' % cxx_generator_root) 134 if platform == 'win32': 135 path_env = os.environ['PATH'] 136 os.putenv('PATH', r'%s;%s\libclang;%s\tools\win32;' % (path_env, cxx_generator_root, cxx_generator_root)) 137 138 139 try: 140 141 tolua_root = '%s/tools/tolua' % project_root 142 output_dir = '%s/cocos/scripting/lua-bindings/auto' % project_root 143 144 cmd_args = { 145 'cocos2dx_fairygui.ini' : ('cocos2dx_fairygui', 'lua_cocos2dx_fairygui_auto'), \ 146 } 147 target = 'lua' 148 generator_py = '%s/generator.py' % cxx_generator_root 149 for key in cmd_args.keys(): 150 args = cmd_args[key] 151 cfg = '%s/%s' % (tolua_root, key) 152 print 'Generating bindings for %s...' % (key[:-4]) 153 command = '%s %s %s -s %s -t %s -o %s -n %s' % (python_bin, generator_py, cfg, args[0], target, output_dir, args[1]) 154 _run_cmd(command) 155 156 print '---------------------------------' 157 print 'Generating lua bindings succeeds.' 158 print '---------------------------------' 159 160 except Exception as e: 161 if e.__class__.__name__ == 'CmdError': 162 print '---------------------------------' 163 print 'Generating lua bindings fails.' 164 print '---------------------------------' 165 sys.exit(1) 166 else: 167 raise 168 169 170 # -------------- main -------------- 171 if __name__ == '__main__': 172 main()
新建cocos2dx_fairygui.ini文件寫入代碼
[cocos2dx_fairygui] # the prefix to be added to the generated functions. You might or might not use this in your own # templates prefix = cocos2dx_fairygui # 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 = fgui 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/../libfairygui/Classes -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 = %(cocosdir)s/../libfairygui/Classes/FairyGUI.h %(cocosdir)s/../libfairygui/Classes/FairyGUIMacros.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 = UIPackage GRoot GObject GComponent UIEventDispatcher GImage GMovieClip GTextField GRichTextField GTextInput GGraph GLoader GGroup GButton GComboBox GProgressBar GSlider GScrollBar GList Window PopupMenu UIObjectFactory GObjectPool DragDropManager FairyGUIMacros EventContext JoystickModule Transition GController ScrollPane InputEvent # 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 classe/s. skip = #skip = UIEventDispatcher::[^addEventListener$ ^removeEventListener$ ^hasEventListener$], # GObject::[^addClickListener$ removeClickListener getData], # GComponent::[^constructFromResource$], # Transition::[^play$ setup], # UIObjectFactory::[setPackageItemExtension], # GController::[setup], # EventContext::[getData] 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 = ArmatureDataManager Manifest # 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
2修改cocos2d-x-3.17.2\tools\bindings-generator\targets\lua\conversions.yaml里的ns_map:下添加fairygui的命名空間"fairygui::": "fgui."

以及在中間to_native:和底部from_native:
to_native:
"Margin": "ok &= luaval_to_margin(tolua_S, ${arg_idx}, &${out_value}, ${lua_namespaced_class_name}:${func_name})"
from_native:
"Margin": "margin_to_luaval(tolua_S, ${in_value})"
2 命令行執行 FairyGUIgenbindings.py. 要用python2版本。執行后在cocos2d-x-3.17.2\cocos\scripting\lua-bindings\auto文件夾下會生成
兩個文件。在C++工程中導入兩個文件。
3 在lua_module_register中include頭文件並注冊
4,編譯運行
5 成功截圖
lua測試代碼(直接用的fairy的demo資源)
注釋:過程中可能會遇到一些問題,由於我是好些天前集成的,遇到的一些問題都忘記截圖了,以上只是大體的流程。
放上一點test的 lua 代碼:
鏈接:https://pan.baidu.com/s/1MSzsX78rZKPV2TQrVWxsmg
提取碼:nh5i