应用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_<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()

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
tolua++是一个将C/C++代码导出到Lua的工具,它可以将C/C++代码转换成Lua解释器调用的API,并在运行时将C/C++代码封装成Lua可用的函数。 以下是一个简单的示例,演示如何使用tolua++C++代码转换成Lua可调用的库: ```c++ // example.h class Example { public: Example(int value); int getValue(); private: int m_value; }; ``` ```c++ // example.cpp #include "example.h" Example::Example(int value) : m_value(value) { } int Example::getValue() { return m_value; } ``` 首先,我们需要使用tolua++生成绑定代码。假设我们的绑定代码文件名为examplebindings.pkg,其内容如下: ``` // examplebindings.pkg $#include "example.h" module example { class Example { public: Example(int value); int getValue(); }; } ``` 然后,我们可以使用tolua++命令行工具将绑定代码生成为C++头文件和Lua文件: ``` $ tolua++ -o examplebindings.h -H examplebindings.hpp examplebindings.pkg ``` 生成的examplebindings.h和examplebindings.hpp文件包含了C++绑定代码,我们需要将其与原始的C++代码一起编译成库文件。 接下来,我们可以编写Lua脚本来调用C++代码: ```lua -- example.lua require "examplebindings" local example = example.Example(42) print(example:getValue()) -- 输出42 ``` 在上面的示例中,我们首先加载了examplebindings模块,然后创建了一个Example对象,并调用了其getValue()方法。注意,我们使用了冒号语法来调用方法,这是Lua中常用的一种语法。 最后,我们可以使用Lua解释器来运行example.lua脚本,以调用C++代码并输出结果。 以上就是使用tolua++C++代码转换成Lua可调用的库的基本流程。需要注意的是,tolua++只支持部分C++特性,例如模板和多重继承等特性可能无法正确导出。在实际使用中,我们需要根据具体情况进行调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值