应用tolua++绑定C++类到lua

  在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__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()

 

你可能感兴趣的:(应用tolua++绑定C++类到lua)