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

2】創建1個pkg文件,這個文件我們只創建1個,作為基礎調用,用來給tolua++使用的,我們待會會詳細說明

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

這些文件的作用,在相干綁定的文章里有詳細介紹,這里略微提1下:
①basic.lua里面規定了tolua++解釋器在解析pkg文件時候的附加規則
②build.sh腳本命令,用來啟動tolua++解釋器解析pkg生成我們需要的那個cpp文件。這里需要改動,由于拷貝了1份在這個目錄下,所以路徑都變了,這里要注意。
#!/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
這里有個"api/LuaAPI.cpp",這是我們指定的要生成的cpp文件,即生成LuaAPI.cpp放在“api/”目錄下(在我們創建的LuaAPI文件夾下)
③build.bat批處理程序,實際上就是履行build.sh里的設置,一樣的,路徑要改1下:
tolua++ -L basic.lua -o "api/LuaAPI.cpp" API.pkg
④tolua++.exe解釋器,用來解析pkg生成cpp的
4】此時,工具已備齊,命令也寫好了,接下來我們要定義1個類,這個類是類似于pkg的描寫文件,只不過以后我們的綁定類都依照pkg的格式寫在這個里邊,而不是寫好多的pkg,并添加到cocos2d.pkg中。
在api目錄下創建1個頭文件:PkgDiscription.h

#ifndef _TEST_PROPERTY_H__
#define _TEST_PROPERTY_H__
#include "cocos2d.h"
USING_NS_CC;
//下面"tolua_begin" and "tolua_end" 這兩行注釋1定不能少,由于它們是辨認的開始和結束
// tolua_begin
//@pkg1_begin 第1個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個自定義類的pkg描寫
//@pkg2_end
// tolua_end
#endif
那末創建這個類有甚么用呢:用來給tolua++去解析編譯的,而tolua++只能編譯pkg,所以我們要把這個類加到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】經過之前的4步,現在直接點擊“build.bat”,就會根據我們寫的“PkgDiscription.h”,生成我們要的“LuaAPI.cpp”文件了,是在api/目錄下

這里面有我們在PkgDiscription.h中聲明要綁定的函數接口。但是發現有毛?。?!
緣由是:在PkgDiscription.h中寫的自定義類MyProperty其實不是我們真實的自定類,它只是1個pkg描寫,那末直接的解決辦法是:在LuaAPI.cpp中引入我們的頭文件“MyProperty.h”
但是這樣不好,每次生成的時候都需要再次引入頭文件,麻煩,但是pkg提供了生成的時候就引入頭文件的辦法,就是在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個新的需要綁定的自定義類,我們都需要這API.pkg中引入,這樣麻煩,那末我們就創建1個總的頭文件類,專門放頭文件:PkgHeadFiles.h
代碼:
#ifndef __PKG_HEAD_FILES_H_
#define __PKG_HEAD_FILES_H_
#include "MyProperty.h"
//在這里引入我們工程中定義的類(準備給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使用的就行了。
關鍵點在CCLuaStack中,看CCLuaStack.cpp文件中init()函數,修改init()函數
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;
}
直接添加會報錯,說找不到這個函數,那末新加的tolua_API_open在哪里呢,實際上是在我們生成的LuaAPI.cpp中,所以為了方便,我們寫1個LuaAPI.h,里面之聲明1下這個函數(單單是為了方便而已)
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中引入這個LuaAPI.h
#include "CCLuaStack.h"
#include "LuaAPI/api/LuaAPI.h" //這里的路徑,由于我已在liblua項目庫目錄中引入相干目錄了,所以用的是相對路徑
好了至此,我們的api目錄下的文件以下:

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