在Lua绑定C++类 .的基础上,使用tolua++自动生成绑定C++类的代码
首先我们要准备tolua++.exe, tulua++.lib文件,如何生成请详看Compiling Toluapp Without Scons,可以使用VS生成.
1、 在Animal.h的基础上,我们编写Animal_tolua.pkg文件
$#include "Animal.h"
class Animal
{
public:
Animal( const char *name );
void setAge( int age );
int getAge();
void sound();
~Animal(void);
};
2、把tolua++.exe, tulua++.lib文件拷贝到Animal_tolua.pkg的同一目录下,使用VS开发人员命令提示工具进入项目目录
输入命令:tolua++ -n tolua -o Animal_tolua.cpp Animal_tolua.pkg
使用tolua++程序,从Animal_tolua.pkg 生成源代码并输出到Animal_tolua.cpp
,而-n参数则是用来指定包名称(lua中package name),你会得到Animal_tolua.cpp文件,
其中包含一个很重要的函数:int tolua_<package name>_oen( lua_State* )
Animal_tolua.cpp
/*
** Lua binding: tolua
** Generated automatically by tolua++-1.0.92 on 03/21/14 11:22:33.
*/
#ifndef __cplusplus
#include "stdlib.h"
#endif
#include "string.h"
#include "tolua++.h"
/* Exported function */
TOLUA_API int tolua_tolua_open (lua_State* tolua_S);
#include "Animal.h"
/* function to release collected object via destructor */
#ifdef __cplusplus
static int tolua_collect_Animal (lua_State* tolua_S)
{
Animal* self = (Animal*) tolua_tousertype(tolua_S,1,0);
Mtolua_delete(self);
return 0;
}
#endif
/* function to register type */
static void tolua_reg_types (lua_State* tolua_S)
{
tolua_usertype(tolua_S,"Animal");
}
/* method: new of class Animal */
#ifndef TOLUA_DISABLE_tolua_tolua_Animal_new00
static int tolua_tolua_Animal_new00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isusertable(tolua_S,1,"Animal",0,&tolua_err) ||
!tolua_isstring(tolua_S,2,0,&tolua_err) ||
!tolua_isnoobj(tolua_S,3,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
const char* name = ((const char*) tolua_tostring(tolua_S,2,0));
{
Animal* tolua_ret = (Animal*) Mtolua_new((Animal)(name));
tolua_pushusertype(tolua_S,(void*)tolua_ret,"Animal");
}
}
return 1;
#ifndef TOLUA_RELEASE
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE
/* method: new_local of class Animal */
#ifndef TOLUA_DISABLE_tolua_tolua_Animal_new00_local
static int tolua_tolua_Animal_new00_local(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isusertable(tolua_S,1,"Animal",0,&tolua_err) ||
!tolua_isstring(tolua_S,2,0,&tolua_err) ||
!tolua_isnoobj(tolua_S,3,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
const char* name = ((const char*) tolua_tostring(tolua_S,2,0));
{
Animal* tolua_ret = (Animal*) Mtolua_new((Animal)(name));
tolua_pushusertype(tolua_S,(void*)tolua_ret,"Animal");
tolua_register_gc(tolua_S,lua_gettop(tolua_S));
}
}
return 1;
#ifndef TOLUA_RELEASE
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE
/* method: setAge of class Animal */
#ifndef TOLUA_DISABLE_tolua_tolua_Animal_setAge00
static int tolua_tolua_Animal_setAge00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"Animal",0,&tolua_err) ||
!tolua_isnumber(tolua_S,2,0,&tolua_err) ||
!tolua_isnoobj(tolua_S,3,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
Animal* self = (Animal*) tolua_tousertype(tolua_S,1,0);
int age = ((int) tolua_tonumber(tolua_S,2,0));
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'setAge'", NULL);
#endif
{
self->setAge(age);
}
}
return 0;
#ifndef TOLUA_RELEASE
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'setAge'.",&tolua_err);
return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE
/* method: getAge of class Animal */
#ifndef TOLUA_DISABLE_tolua_tolua_Animal_getAge00
static int tolua_tolua_Animal_getAge00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"Animal",0,&tolua_err) ||
!tolua_isnoobj(tolua_S,2,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
Animal* self = (Animal*) tolua_tousertype(tolua_S,1,0);
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'getAge'", NULL);
#endif
{
int tolua_ret = (int) self->getAge();
tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
}
}
return 1;
#ifndef TOLUA_RELEASE
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'getAge'.",&tolua_err);
return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE
/* method: sound of class Animal */
#ifndef TOLUA_DISABLE_tolua_tolua_Animal_sound00
static int tolua_tolua_Animal_sound00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"Animal",0,&tolua_err) ||
!tolua_isnoobj(tolua_S,2,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
Animal* self = (Animal*) tolua_tousertype(tolua_S,1,0);
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'sound'", NULL);
#endif
{
self->sound();
}
}
return 0;
#ifndef TOLUA_RELEASE
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'sound'.",&tolua_err);
return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE
/* method: delete of class Animal */
#ifndef TOLUA_DISABLE_tolua_tolua_Animal_delete00
static int tolua_tolua_Animal_delete00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"Animal",0,&tolua_err) ||
!tolua_isnoobj(tolua_S,2,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
Animal* self = (Animal*) tolua_tousertype(tolua_S,1,0);
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL);
#endif
Mtolua_delete(self);
}
return 0;
#ifndef TOLUA_RELEASE
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err);
return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE
/* Open function */
TOLUA_API int tolua_tolua_open (lua_State* tolua_S)
{
tolua_open(tolua_S);
tolua_reg_types(tolua_S);
tolua_module(tolua_S,NULL,0);
tolua_beginmodule(tolua_S,NULL);
#ifdef __cplusplus
tolua_cclass(tolua_S,"Animal","Animal","",tolua_collect_Animal);
#else
tolua_cclass(tolua_S,"Animal","Animal","",NULL);
#endif
tolua_beginmodule(tolua_S,"Animal");
tolua_function(tolua_S,"new",tolua_tolua_Animal_new00);
tolua_function(tolua_S,"new_local",tolua_tolua_Animal_new00_local);
tolua_function(tolua_S,".call",tolua_tolua_Animal_new00_local);
tolua_function(tolua_S,"setAge",tolua_tolua_Animal_setAge00);
tolua_function(tolua_S,"getAge",tolua_tolua_Animal_getAge00);
tolua_function(tolua_S,"sound",tolua_tolua_Animal_sound00);
tolua_function(tolua_S,"delete",tolua_tolua_Animal_delete00);
tolua_endmodule(tolua_S);
tolua_endmodule(tolua_S);
return 1;
}
#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 501
TOLUA_API int luaopen_tolua (lua_State* tolua_S) {
return tolua_tolua_open(tolua_S);
};
#endif
3、修改TestCpp.h 添加这行代码:tolua_tolua_open(l);
// TestLua.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "Utlis.h"
#include "LuaAnimal.h"
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
lua_State *l = lua_open();
luaL_openlibs(l);
///LuaAnimal::Register(l);
Utlis::stackDump(l);
tolua_tolua_open(l);
if( luaL_dofile( l, "main.lua" )){ // load and call
Utlis::stackDump(l);
}
Utlis::stackDump(l);
system("pause");
lua_close(l);
return 0;
}
3、修改main.lua,把Animal:create 修改为Animal:new( tolua++自己生成的是new,可以手动修改为create,只是一个名字而已,最后运行应该就ok了
print( "test lua access C++ class" )
local function main()
--local s = Animal:create("xx")
local s = Animal:new("xx")
s:setAge(100)
s:sound()
end
main()