cocos2dx 2.x版本:簡化提煉tolua++綁定自定義類到lua中使用
來源:程序員人生 發(fā)布時(shí)間:2015-02-03 08:38:09 閱讀次數(shù):4805次
cocos2dx的3.x版本已提供了更好地綁定方式,網(wǎng)上有很多相干的教程,這里給1個(gè)鏈接:http://www.cocoachina.com/bbs/read.php?tid=196416。
由于目前我們的項(xiàng)目使用的是2.x版本的,且已開發(fā)了1半了,這時(shí)候候不合適轉(zhuǎn)3.x的版本,因而只能用2.x的老方法tolua++來實(shí)現(xiàn)綁定。這就有1個(gè)蛋疼的問題,太麻煩!每次都要寫pkg、使用tolua++.exe解釋器編譯生成新的cpp,在其中添加自己的類的頭文件援用,然后把這個(gè)新的cpp文件覆蓋到liblua中之前的,再編譯庫,生成新的obj,才算完事。這里給出木頭大神的文章,里面寫的很清楚:http://blog.csdn.net/musicvs/article/details/8166572/。
可是我不想每次都這樣麻煩,我希望在自己的工程里添加綁定的接口,這樣每次運(yùn)行時(shí)只更新我自己的項(xiàng)目,就能夠讓lua辨認(rèn)我的類。初1想,那就把“LuaCocos2d.cpp”這個(gè)類放到項(xiàng)目中如何,這個(gè)想法完全可以的,即我們新的綁定就不再添加到“LuaCocos2d.cpp”這里了,而是單獨(dú)生成1個(gè)新的、只有我們自己的的綁定類接口的1個(gè)類放到工程中。好了,空話不多說,看流程
1】首先在我們自己的項(xiàng)目中創(chuàng)建1個(gè)文件夾,專門寄存對lua的綁定接口類和相干文件:LuaAPI

2】創(chuàng)建1個(gè)pkg文件,這個(gè)文件我們只創(chuàng)建1個(gè),作為基礎(chǔ)調(diào)用,用來給tolua++使用的,我們待會(huì)會(huì)詳細(xì)說明

3】將cocos2d-x⑵.2.3 ools olua++目錄下的3個(gè)文件拷貝到1】中創(chuàng)建的文件里,這是工具,用來生成用的,這個(gè)不能少

這些文件的作用,在相干綁定的文章里有詳細(xì)介紹,這里略微提1下:
①basic.lua里面規(guī)定了tolua++解釋器在解析pkg文件時(shí)候的附加規(guī)則
②build.sh腳本命令,用來啟動(dòng)tolua++解釋器解析pkg生成我們需要的那個(gè)cpp文件。這里需要改動(dòng),由于拷貝了1份在這個(gè)目錄下,所以路徑都變了,這里要注意。
#!/bin/bash
#
# Invoked build.xml, overriding the lolua++ property
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
TOLUA=`D:cocos2d-x⑵.2.3projectsactgameluaClassesLuaAPI`
if [ -z "${TOLUA}" ]; then
TOLUA=`D:cocos2d-x⑵.2.3projectsactgameluaClassesLuaAPI`
fi
if [ -z "${TOLUA}" ]; then
echo "Unable to find tolua++ (or tolua++5.1) in your PATH."
exit 1
fi
cd ${SCRIPT_DIR}
${TOLUA} -L basic.lua -o "api/LuaAPI.cpp" API.pkg
這里有個(gè)"api/LuaAPI.cpp",這是我們指定的要生成的cpp文件,即生成LuaAPI.cpp放在“api/”目錄下(在我們創(chuàng)建的LuaAPI文件夾下)
③build.bat批處理程序,實(shí)際上就是履行build.sh里的設(shè)置,一樣的,路徑要改1下:
tolua++ -L basic.lua -o "api/LuaAPI.cpp" API.pkg
④tolua++.exe解釋器,用來解析pkg生成cpp的
4】此時(shí),工具已備齊,命令也寫好了,接下來我們要定義1個(gè)類,這個(gè)類是類似于pkg的描寫文件,只不過以后我們的綁定類都依照pkg的格式寫在這個(gè)里邊,而不是寫好多的pkg,并添加到cocos2d.pkg中。
在api目錄下創(chuàng)建1個(gè)頭文件:PkgDiscription.h

#ifndef _TEST_PROPERTY_H__
#define _TEST_PROPERTY_H__
#include "cocos2d.h"
USING_NS_CC;
//下面"tolua_begin" and "tolua_end" 這兩行注釋1定不能少,由于它們是辨認(rèn)的開始和結(jié)束
// tolua_begin
//@pkg1_begin 第1個(gè)pkg描寫文件開始
class MyProperty : public CCObject
{
MyProperty (void);
~MyProperty (void);
void setUniqueId(int id);
int getUniqueId();
void setRoleName(const char *name);
const char* getRoleName();
};
//@pkg1_end
//@pkg2_begin
//這里寄存下1個(gè)自定義類的pkg描寫
//@pkg2_end
// tolua_end
#endif
那末創(chuàng)建這個(gè)類有甚么用呢:用來給tolua++去解析編譯的,而tolua++只能編譯pkg,所以我們要把這個(gè)類加到API.pkg中
typedef unsigned char BYTE;
typedef int BOOL;
typedef unsigned long DWORD;
typedef unsigned short WORD;
typedef char* LPSTR;
typedef const char* LPCSTR;
$cfile "api/PkgDiscription.h"
5】經(jīng)過之前的4步,現(xiàn)在直接點(diǎn)擊“build.bat”,就會(huì)根據(jù)我們寫的“PkgDiscription.h”,生成我們要的“LuaAPI.cpp”文件了,是在api/目錄下

這里面有我們在PkgDiscription.h中聲明要綁定的函數(shù)接口。但是發(fā)現(xiàn)有毛病!!
緣由是:在PkgDiscription.h中寫的自定義類MyProperty其實(shí)不是我們真實(shí)的自定類,它只是1個(gè)pkg描寫,那末直接的解決辦法是:在LuaAPI.cpp中引入我們的頭文件“MyProperty.h”
但是這樣不好,每次生成的時(shí)候都需要再次引入頭文件,麻煩,但是pkg提供了生成的時(shí)候就引入頭文件的辦法,就是在API.pkg中添加頭文件。
typedef unsigned char BYTE;
typedef int BOOL;
typedef unsigned long DWORD;
typedef unsigned short WORD;
typedef char* LPSTR;
typedef const char* LPCSTR;
$cfile "api/PkgDiscription.h"
$#include "MyProperty.h"
但是這樣還不好,由于每有1個(gè)新的需要綁定的自定義類,我們都需要這API.pkg中引入,這樣麻煩,那末我們就創(chuàng)建1個(gè)總的頭文件類,專門放頭文件:PkgHeadFiles.h
代碼:
#ifndef __PKG_HEAD_FILES_H_
#define __PKG_HEAD_FILES_H_
#include "MyProperty.h"
//在這里引入我們工程中定義的類(準(zhǔn)備給lua用的)
#endif
因而在API.pkg中
typedef unsigned char BYTE;
typedef int BOOL;
typedef unsigned long DWORD;
typedef unsigned short WORD;
typedef char* LPSTR;
typedef const char* LPCSTR;
$cfile "api/PkgDiscription.h"
$#include "PkgHeadFiles.h"
6】到這里基本已大功告成了,但是還有1步,就是我們自己生成的LuaAPI.cpp文件,是怎樣給lua使用的呢,那末只需要知道引擎本身的LuaCocos2d.cpp是怎樣給lua使用的就行了。
關(guān)鍵點(diǎn)在CCLuaStack中,看CCLuaStack.cpp文件中init()函數(shù),修改init()函數(shù)
bool CCLuaStack::init(void)
{
//....
tolua_CocoStudio_open(m_state);
//新加的1句代碼
tolua_API_open(m_state);
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
CCLuaObjcBridge::luaopen_luaoc(m_state);
#endif
//.….
return true;
}
直接添加會(huì)報(bào)錯(cuò),說找不到這個(gè)函數(shù),那末新加的tolua_API_open在哪里呢,實(shí)際上是在我們生成的LuaAPI.cpp中,所以為了方便,我們寫1個(gè)LuaAPI.h,里面之聲明1下這個(gè)函數(shù)(單單是為了方便而已)
LuaAPI.h代碼:
#ifndef __LUA_API_H_
#define __LUA_API_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "tolua++.h"
#ifdef __cplusplus
}
#endif
TOLUA_API int tolua_API_open(lua_State* tolua_S);
#endif
然后在CCLuaStack中引入這個(gè)LuaAPI.h
#include "CCLuaStack.h"
#include "LuaAPI/api/LuaAPI.h" //這里的路徑,由于我已在liblua項(xiàng)目庫目錄中引入相干目錄了,所以用的是相對路徑
好了至此,我們的api目錄下的文件以下:

當(dāng)項(xiàng)目完成以后后兩個(gè)頭文件可以刪除,現(xiàn)在它只是方便書寫而已。
這樣,每次需要修改文件時(shí),在“PkgHeadFiles.h”引入我們自定義的類,在“PkgDiscription.h”中添加pkg描寫,然后運(yùn)行1下build.bat便可。都是在我們自己的工程中操作的,上傳svn。
生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)