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。