Quick-Cocos2dx-Community lua繫結,lua呼叫C++ 類
這裡有篇文章,看三和四。
按上面操作,檔案都不缺少的,可以直接看 2. 和 3 .
記住:player3 來開啟專案, 的類格式化後,放到他的原始碼路徑下面, 解釋生成的lua 也要放到 api下面
player3 重新生成就可以了
player3 最後開啟可能會出現, a nil value。
其實,我們用cocos2d-x-3.10,
D:\cocos\setup\Cocos2d-x\cocos2d-x-3.10\tools\tolua
genbindings.py **.ini 來轉換成 lua能夠呼叫的 類。
其實就是通過D:\cocos\setup\Cocos2d-x\cocos2d-x-3.10\tools\tolua下提供:
我的環境:
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:\Game\Quick-Cocos2dx-Community\tools\tolua
下面,按住shift + 右鍵點選選擇 “在此處開啟命令視窗”直接執行 python genbindings.py。 試試你的Quick-Cocos2dx-Community 能不能轉換。
如果不行,也沒有關係,這個時候,需要 cocos2d-x 引擎來處理, 我的是 cocos2d-x-3.10。
1.
把自己的類,.h .cpp 放到 G:\ademo\frameworks\runtime-src\Classes 這個下面 “runtime-src\Classes”, 這裡的工程是G:\下的 ademo,
(名字有點怪, demo 前面加個a 是便於 player3 開啟專案是 目錄 在最上面。)
接下來是 cocos2d-x-3.10解壓安裝目錄下
D:\cocos\setup\Cocos2d-x\cocos2d-x-3.10\tools\tolua
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-src\Classes自己的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
output_dir = '%s/cocos/scripting/lua-bindings/auto' % 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, 'toolchains/llvm-3.3/prebuilt', '%s-%s' % (cur_platform, 'x86')))
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-%s' % (cur_platform, 'x86')))
x64_llvm_path = os.path.abspath(os.path.join(ndk_root, 'toolchains/llvm-3.3/prebuilt', '%s-%s' % (cur_platform, 'x86_64')))
if not os.path.exists(x64_llvm_path):
x64_llvm_path = os.path.abspath(os.path.join(ndk_root, 'toolchains/llvm-3.4/prebuilt', '%s-%s' % (cur_platform, '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', 'extra_flags', '-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;%s\libclang;%s\tools\win32;' % (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', '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 *')
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:\cocos\setup\Cocos2d-x\cocos2d-x-3.10\cocos\scripting\lua-bindings\auto
lua格式的c++ 類 lua_pet_auto.hpp lua_pet_auto.cpp
D:\cocos\setup\Cocos2d-x\cocos2d-x-3.10\cocos\scripting\lua-bindings\auto\api
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.cx, display.cy + 100)
:addTo(self)
end
你要確保你的vs工程下面 libluacocos2d -auto : lua_pet_auto.cpp 和 lua_pet_auto.hpp 存在。
這個我是放在 player3 原始碼 路徑下的:G:\Game\Quick-Cocos2dx-Community\cocos\scripting\lua-bindings\auto
可以直接 右鍵屬性, c++ 標頭檔案路徑匯入 絕對路徑 G:\ademo\frameworks\runtime-src\Classes\
Pet.h Pet.cpp
這裡配置成功後, 後面需要開啟的另一個工程就不需要配置了。
你的工程 下(這裡我的是ademo) 下面 右鍵屬性 G:\Game\Quick-Cocos2dx-Community\cocos\scripting\lua-bindings\auto
lua_pet_auto.cpp 和 lua_pet_auto.hpp 存在
G:\Game\Quick-Cocos2dx-Community\cocos\scripting\lua-bindings\auto\api
lua_pet_auto_api.lua 和 Pet.lua 存在
就是 把 cocos2d-x-3.10 下成才的東西 player3 在放置一下,因為你是用 player3嗎,對吧!
注意:你用的是player3 ,但此時,為什麼沒有成功,這是為什麼呢? 嘿嘿。
雖說你的 lua_pet_auto.cpp 和 lua_pet_auto.hpp 也放到 player3 的資源目錄下啦(G:\Game\Quick-Cocos2dx-Community\cocos\scripting\lua-bindings\auto)
lua_pet_auto_api.lua 和 Pet.lua
也在 G:\Game\Quick-Cocos2dx-Community\cocos\scripting\lua-bindings\auto\api 下了。
為什麼呢?
—— vs 開啟工程 重新構建 ,build all 。 把所有的東西 整合。
因為 你用的 player3 ,是編譯生成好的 。
3. 那好,我們來操作....
G:\Game\Quick-Cocos2dx-Community\quick\player
找到 proj.win32 vs 開啟 解決方案 player.sln 重新 生成解決方案。
返回到上級目錄 :G:\Game\Quick-Cocos2dx-Community\quick\player
win32 資料夾 ,就是 你的player3(桌面沒有的 ,右鍵桌面快捷方式)
重新生成解決方案後,開啟看看,是不是成功了。
注意:vs 開啟 解決方案 player.sln 下 專案 libluacocos2d 和你工程的 應該是一樣的, 這也是上面我們提到的你會用到的。
只需要 player3 工程 下 class 右鍵新增
G:\Game\Quick-Cocos2dx-Community\quick\player\Classes\ Pet.h Pet.cpp 這裡是從你的工程下 “\frameworks\runtime-src\Classes” 下哪來的
這也是 為什麼 開始 讓你 Quick-Cocos2dx-Community 下試試 能不能執行成功的原因, 成功了,就不需要 cocos2d-x-3.10 來生成
直接 在G:\Game\Quick-Cocos2dx-Community\tools\tolua 生成, 後面不要 複製過來複制過去了。
好了完了。
補充:
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
以上僅供參考,歡迎留言指正錯誤! 附上郵箱:[email protected]