刚接触quick coco2dx,在lua代码里面,用到的类和函数,一般都在framework里能找到定义,但同时发现lua代码里面调用了大量跟原C++编写的cocos2dx同名的类,就有一个疑惑,难道lua可以直接调用C++类?像以下部分的代码调用:
function game.startup()
CCFileUtils:sharedFileUtils():addSearchPath("res/")
display.addSpriteFramesWithFile(GAME_TEXTURE_DATA_FILENAME, GAME_TEXTURE_IMAGE_FILENAME)
game.enterMainScene()
end
CCFileUtils在framework里找不到定义,类名跟cocos2dx的类名完全相同。还有:
function game.exit()
CCDirector:sharedDirector():endToLua()
end
里面的CCDirector
function SpriteItem:getContentWidth()
local itemWidth = 0
if (0 == itemWidth) then
local sprite = display.newSprite("#sushi_1n.png")
itemWidth = sprite:getContentSize().width
end
return itemWidth
end
里面的sprite
事实上,lua是不能直接调用C++的类和函数,quick cocos2dx只不过将lua调用C++的机制进行了封装。
D:\quick\quick-cocos2d-x-2.2.5\lib\cocos2d-x\external\extra\luabinding下面(这是我所在的quick cocos2dx的路径),官方的文档:“请参考 quick 项目 lib/cocos2dx_extra 目录中的文件。大概步骤:1.从 .h 文件创建 .pkg 文件,2.运行 tolua++ 根据 .pkg 创建相应的 .cpp/.h 文件。3. 导入 .cpp/.h 文件到项目中。4. 在 AppDelegate.cpp 中添加 .h 文件包含的 tolua_XXX_open() 函数。”
这就是指导如何将C++类转化可以在lua中调用的类的步骤。在quick cocos2dx里面作了更深层次的封装,在这个目录下面有个build.sh
#!/usr/bin/env bash
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd "$DIR"
OUTPUT_DIR="$DIR"
MAKE_LUABINDING="$QUICK_COCOS2DX_ROOT"/bin/compile_luabinding.sh
$MAKE_LUABINDING -E CCOBJECTS=CCHTTPRequest -d "$OUTPUT_DIR" cocos2dx_extra_luabinding.tolua
echo ""
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
echo ""
$MAKE_LUABINDING -d "$OUTPUT_DIR" cocos2dx_extra_ios_iap_luabinding.tolua
echo ""
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
echo ""
$MAKE_LUABINDING -d "$OUTPUT_DIR" CZHelperFunc_luabinding.tolua
先是定义输出路径,输出路径在:lib\cocos2d-x\external\extra\luabinding
然后make_luabinding的路径是/bin/compile_luabinding.sh
这个脚本会调用一个PHP脚本bin/lib/complile_luabinding.php
具体做法是
1.首先在lib\cocos2d-x\external\extra\目录下创建目录并实现自己的类,比如在apptools目录下定义并实现了类CZHelperFunc;
2.在lib\cocos2d-x\external\extra\luabinding目录下打开文件CZHelperFunc_luabinding.tolua
$#include "../apptools/HelperFunc.h"
class CZHelperFunc
{
static LUA_STRING getFileData(const char *pPathFile);
};
这是具体的样式,以便生成lua可以调用的C++类
3.然后调用build_CZHelperFunc_luabinding脚本生成CZHelperFunc_luabinding.h和CZHelperFunc_luabinding.cpp,脚本内容如下:
@echo off
set DIR=%~dp0
set OUTPUT_DIR=%DIR%
set MAKE_LUABINDING="%QUICK_COCOS2DX_ROOT%\bin\compile_luabinding.bat"
pushd
cd "%DIR%"
call %MAKE_LUABINDING% -E CZHelperFunc -d %OUTPUT_DIR% CZHelperFunc_luabinding.tolua
echo.
echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
echo.
rem call %MAKE_LUABINDING% -d %OUTPUT_DIR% cocos2dx_extra_ios_iap_luabinding.tolua
popd
实质上还是调用compile_luabinding.bat来进行转换 -E指定待转换的C++类名 -d指定输出路径
自此,lua中就可以调用CZHelperFunc 这个C++类了。
因此,cocos2dx里面大量的C++实现的类,都是通过这种方式来完成转换,因此quick cocos2dx的lua里面可以自由调用到cocos2dx的C++类。
在D:\quick\quick-cocos2d-x-2.2.5\lib\luabinding目录下面,打开build.sh
#!/bin/bash
DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
TOLUA="$QUICK_COCOS2DX_ROOT/bin/mac/tolua++"
cd "$DIR/"
${TOLUA} -L "$DIR/basic.lua" -o "$QUICK_COCOS2DX_ROOT/lib/cocos2d-x/scripting/lua/cocos2dx_support/LuaCocos2d.cpp" Cocos2d.tolua
-- tolua++ "-L" "basic.lua" "-o" "../../scripting/lua/cocos2dx_support/LuaCocos2d.cpp" "Cocos2d.pkg"
这句命令执行,应该就实现了lua跟C++的绑定,因此lua可以调用cocos2dx的c++类,至于原理如何,目前还不清楚,有待更深入地研究。