使用tolua++实现C++与LUA相互调用

游戏服务器之第三方库tolua++的使用 tolua++ 是使用lua与c++交互的第三方库。可以跨windows和linux平台的。 使用步骤: 1、把tolua++.exe(在tolua++-1.0.93.rar中) 添加到环境变量path中(或者把tolua++.exe、lua5.1.dll放到当前目录) 2、复制头文件到文件夹pack(若新加头文件,否则就直接修改对应pkg文件) 3、把头文件拓展名改为pkg 4 阅读详情

LUA是一种目前很流行的高效精简的脚本语言。LUA一个特点是比较方便的与C通讯。

然而要在脚本中使用C++类使用基本的LUA方法还是比较麻烦,纯手工暴露一个类的接口到LUA工作量还是很大的,而且都是一些简单的重复劳动。

好在有tolua++这个工具,可以让程序员从简单的重复劳动解脱出来。

tolua++包含两个部分,一个EXE,一个LIB,EXE用来通过package文件生成C函数的胶水函数,而LIB则用来为生成的胶水函数中用到的辅助函数提供实现。

 

在lua中要调用一个已有的C函数,大体上可以包含2步:

1、在C程序中实现一个胶水函数,该函数只有一个参数lua_State *。在这个胶水函数中,从lua的参数栈中逐个取出参数,再调用原有的C函数,最后将C函数的返回结果通过LUA的栈传回给LUA环境。

2、将该胶水函数注册到LUA的全局表中。

虽然这两个过程都很简单,但是当要暴露的是C++类大量的成员函数时,为每个函数编写胶水函数的工作可想而知。

有了tolua++,这个工作就很简单了,只需要做很少的工作就可以让tolua++自动为每一个待暴露的函数实现胶水函数。

如下面这样一个C++类,类的实现在一个命名空间TstNS中,类中包含有同一函数名的不同重载及自定义的结构体参数:

//file:export.h

#pragma once

#include <string>

using namespace std;

namespace TstNS

{

	struct RECT

	{

		int left, top, right, bottom;

	};

	class CExport

	{

	public:

		CExport(void);

		~CExport(void);



		int foo(int a, int b);

		int StrLen(const string & str);

		int StrLen(const char *pstr);

		int area(RECT rc);

		int area(RECT *prc);

		RECT setrect(int l, int t, int r, int b);

	};

}

为了使用tolua++导出这个类到lua中,我们需要写一个package文件,在该文件中定义哪里函数需要导出,我这里的实现如下:

//file:export.pkg



$#include "export.h"



namespace TstNS

{

	struct RECT

	{

		int left, top, right, bottom;

	};



	class CExport

	{

		CExport();

		~CExport();

		int foo(int a, int b);

		int StrLen(const string & str);

		int StrLen @ StrLen2(const char *pstr);

		int area(RECT rc);

		int area @ area2(RECT *prc); //将对area(void * prect)的调用重命名为area2

		RECT setrect(int l, int t, int r, int b);



	};

}

整 体上export.pkg中的内容基本与export.h文件类似,需要注意的是第一行:$#include "export.h"。tolua++根据这个文件来为其中的每个函数生成胶水函数于一个C文件中,由于胶水函数需要调用原来的函数,所以需要在生成的C 文件中需要包含export.h这个文件。第一行就是说在生成的C文件中插入一行#include “export.h"

第二个需要注意的地方在于函数的重载,LUA并不能根据参考类型自动选择调用哪一个重载函数,为此我们可以为不同的重载重命名。”@“正是为这一目的设计的。通过重命名,在LUA脚本中我们就可以显示的为不同的参数调用不同的重载函数。

我们需要使用tolua++的EXE来生成胶水函数代码。它是一个命令行程序,可以多个参数:

..\..\tolua++-1.0.93\bin\tolua++ -n export -o ..\lua_export.cpp export.pkg

这一行的意思是说调用tolua++.exe根据export.pkg生成一个..\lua_export.cpp的C++文件。-n export是说文件中一个需要被外面调用的C接口为:

int tolua_export_open (lua_State* tolua_S);

下一步,我们看一下在lua脚本中如何调用我们的导出的函数。

--file:test.lua

exp=TstNS.CExport:new();--首先我实例化一个CExport的全局对象。



function foo(a,b)

return exp:foo(a,b);

end



function StrLen(str)

return exp:StrLen(str);

end



function StrLen2(str)

return exp:StrLen2(str);

end



function area(rc)

return exp:area(rc);

end



function area2(prc)

--指针参数使用lua_call.hpp将以void*方式传入,需要做类型转换后才能调用C++中的代码。

return exp:area2(tolua.cast(prc,"TstNS::RECT"));

end



function setrect(l,t,r,b)

return exp:setrect(l,t,r,b);

end

在这个test.lua中我们实现了几个函数,在每一个函数中会调用CExport对应的接口。

到此lua调用C++的基本框架就已经实现了。

 

下面再看这个demo如何工作。

找到代码中的luatest目录,并打开luatest.sln这个VC工程,上面提到的代码在工程中都可以找到。

直接编译可以查看每一个函数是如何被调用的。

这里要推荐一个我改写的在C++中调用LUA函数的辅助模板类:lua_call.hpp

采用这个辅助类调用LUA函数就和调用普通的C函数一样简单。

下面是luatest.cpp中的代码:


 

// luatest.cpp : 定义控制台应用程序的入口点。

//



#include "stdafx.h"



#include "Export.h"

#include "tolua++.h"



extern int  tolua_export_open(lua_State* tolua_S);



#include "lua_call.hpp"//使用模板技术对C++调用lua函数进行包装,使用方法参见_tmain

//对于自定义的数据类型,需要特化push_value,及value_extractor两个接口。

template<>

void lua_function_base::push_value(TstNS::RECT rc)

{

	void* tolua_obj = Mtolua_new((TstNS::RECT)(rc));

	tolua_pushusertype(m_vm, tolua_obj, "TstNS::RECT");

	tolua_register_gc(m_vm, lua_gettop(m_vm));

}



template <>

TstNS::RECT lua_function_base::value_extractor()

{

	TstNS::RECT * val = (TstNS::RECT *) tolua_tousertype(m_vm, -1, 0);

	lua_pop(m_vm, 1);

	return *val;

}



int _tmain(int argc, _TCHAR* argv[])

{

	lua_State *L = lua_open();

	int nret = 0;

	luaL_openlibs(L);

	nret = tolua_export_open(L);

	nret = luaL_dofile(L, "lua/test.lua");



	{

		lua_function<int> lua_area(L, "area");

		TstNS::RECT rc = { 0,0,10,20 };

		int a1 = lua_area(rc);



		lua_function<int> lua_area2(L, "area2");

		TstNS::RECT rc2 = { 0,0,100,20 };

		int a2 = lua_area2(&rc2);



		lua_function<TstNS::RECT> lua_setarea(L, "setrect");

		rc = lua_setarea(5, 6, 7, 8);



		lua_function<int> lus_strlen(L, "StrLen");

		int nsize1 = lus_strlen(std::string("abcdefghij"));



		lua_function<int> lus_strlen2(L, "StrLen2");

		int nsize2 = lus_strlen("abcdefg");



		lua_function<int> foo(L, "foo");

		int sum = foo(5, 6);

	}



	lua_close(L);

	return 0;

}

 

在_main()中,首先当然是实例化lua环境。

调用tolua_export_open(L);注册tolua++实现的胶水函数到LUA。

调用luaL_dofile(L,"lua/test.lua");执行test.lua脚本。

 

调用lua脚本中实现的函数。

 

最后释放LUA环境:lua_close(L);

 

这其中lua脚本中实现的函数是比较取巧的。利用lua_call.hpp,我们只需要两行代码就可以实现:

第一步,定义一个lua_function对象,找到LUA中的函数。

第二步,为函数传入参数。

 

需要注意的是,当为CExport新增加一个需要导出的函数时,要记得将新的函数名加到export.pkg文件中,并调用tolua++重新生成胶水函数。在demo中有一个build.bat文件,每次更新后执行一次即可。

lua学习03:tolua的编译和使用:C/C++调用lua、lua调用C++、lua调用tolua、常用tolua和lua的API介绍 文章目录一、编译及使用流程1)编译lua静态库2)编译tolua++静态库3)编译tolua++.exe4)根据C/C++文件编写好对应的pkg文件,然后根据一创命令生成tolua(1)C文件举例(2)C++文件举例二、C++调用lua三、lua调用C++ 一、编译及使用流程 1)编译lua静态库 必须先下载lua 1.5,下载好后,把/src目录的除开lua.c,luac.c的文件全部放到一个新建的静态链接库的工程项目里,然后编译出一个静态链接库lua.lib。 2)编译tolua++静态库 去tolua 阅读详情

相关推荐

【lua】使用 tolua 实现 lua 与 c++ 交互

tolua 也叫 tolua++,是一个第三方库,简化了 lua 访问 c/c++ 的工作。tolua 自动导出 c/c++ 中的常量、变量、函数、类等,提供给 lua 直接访问和调用。lua 与 c 是可以直接相互访问的,不使用 tolua 或其它第三方库也可以实现 lua 调用 c/c++,但比较麻烦,开发效率太低。

xingxinmanong的博客 6328

tolua++简介

 2005年12月27日23:07:59一.tolua++简介      tolua++是一种第三方的软件包,可以为Lua提供面向对象的特性,这样我们就可以使用Lua来编写使用C++语言库的脚本文件.二.tolua++的编译.     tolua++的主页在http://www.codenix.com/~tolua/,目前的最新版本是1.0.7,为了使用tolua++,我们需要三个文件

answer的专栏 4万+

【COCOS2DX-LUA 脚本开发之四】使用tolua++编译pkg,从而创建自定义类让Lua脚本使用

本站文章均为 李华明Himi 原创,转载务必在明显处注明:(作者新浪微博: @李华明Himi ) 转载自【黑米GameDev街区】 原文链接: http://www.himigame.com/lua1/1259.html           ☞ 点击订阅 ☜ 本博客最新动态!及时将最新博文通知您!                 此篇基本【COCOS2DX(2.X)_LUA开发之三】在LUA中使用

李华明Himi 1万+

【cocos2d-x + Lua(1) 绑定Lua并使用tolua++】

为什么要使用Lua进行游戏开发?转载请注明出处http://www.cnblogs.com/zisou/p/cocos2dx-lua1.html 上面一个问题我觉得在我们使用Lua之前需要深入思考的,Lua有何优点?缺点又是什么?先找准自己的项目定位 在什么时候使用是很必要的; 经过自己一番摸索之后有如下结论: 优点: 1,嵌入式脚本开发可以跳过平台市场进行独立的游戏资源更新; 2,在...

weixin_30374009的博客 88

lua调用c++的函数 使用tolua++

1.定义C++类与函数 #include class cppFunctions { public: static double getCurrentTime(); }; #include "cppFunctions.h" #include #include //使用linux下获取时间的函数 double cppFunctions::getCurrentTime() {

375

tolua++ 编译 及使用 简单介绍

tolua++ 编译 及使用 简单介绍 tolua++ 是用来把 C++代码 生成 在Lua中使用的接口的工具,编译步骤比较繁琐。

[cocos2d-x3.2]Lua调用自定义C++类和函数

关于cocos2d-x下Lua调用C++的文档看了不少,但没有一篇真正把这事给讲明白了,我自己也是个初学者,摸索了半天,总结如下:cocos2d-x下Lua调用C++这事之所以看起来这么复杂、网上所有的文档都没讲清楚,是因为存在5个层面的知识点:1、在纯C环境下,把C函数注册进Lua环境,理解Lua和C之间可以互相调用的本质2、在cocos2d-x项目里,把纯C函数注册进Lu...

weixin_34248023的博客 117

深交所 vs 上交所:Level-2实时数据推送规则详解与策略适配指南

本文深度解析沪深Level-2实时数据推送规则的关键差异,包括逐笔成交、逐笔委托和10档行情接口的处理逻辑。针对高频交易策略,详细对比上交所与深交所在数据推送机制、时间戳处理及委托队列解析等方面的差异,并提供具体的策略适配方案和性能优化建议,帮助量化投资者提升跨市场交易稳定性。

weixin_27310417的博客 1163

利用tolua++编译pkg,以便让Lua使用cpp自定义类

欢迎各位童鞋转载,转载请注明出处:http://blog.youkuaiyun.com/song_hui_xiang 作者新浪微博:http://weibo.com/u/3168848533 作者腾讯微博:http://t.qq.com/song_huixiang 1、创建自定义类SongCpp.cpp SongCpp.h #ifndef __SongToLua__SongCpp

song_hui_xiang 7936

常规波束形成——时域波束形成、频域波束形成

本文介绍了波束成形,包括时域波束成形和频域波束成形,并解释了在实现过程可能存在疑惑的相位补偿。

Candy_Editor的博客 3657

DRM驱动架构浅析-上(DRM基础概要与U-Boot阶段驱动解析)

本文主要探讨了Rockchip平台的DRM显示驱动架构及其在U-Boot阶段的实现。

一路寒风身如絮,命海沉浮客独行 1761

Lua学习之3 :tolua++导出C++变量给Lua使用

一. 分享内容        主要分享如何使用tolua++导出C++中的变量,使lua能够直接使用导出的C++变量。 二. 开始分享     在Lua学习之1 :C++调用Lua函数和Lua学习之2 :Lua调用C++函数中学习了C++和Lua 之间的相互调用,知道了怎么暴露一个C++函数给Lua。然而,如果需要暴露给Lua的C++函数巨 多的话,那手工暴露的

ConnorWang2012的专栏 2608

如何用谷歌插件Apollo.io高效开发客户?手把手教你避开常见坑点

本文详细介绍了如何利用谷歌插件Apollo.io高效开发外贸客户,包括核心功能解析、免费额度最大化利用策略、多插件协同技巧以及常见陷阱规避方法。通过Apollo.io的智能匹配算法和庞大数据库,外贸从业者可以精准锁定目标客户,提升开发效率。

banana的博客 885

tolua++实现lua层调用c++技术分析

tolua++需要将 c/c++ 中的类型,变量,函数,对象导出到lua 通过 tolua_reg_types(lua_State* tolua_S) 将类型导出,作用是为每一个需要导出到 lua 中的 c++ 类型创建元表,比如 CCNode 这种类型,就会在注册表中创建一个元表 CCNode_mt。( 之后会用 _R 代表注册表 , _G 代表全局表 , type_mt 代表类型为...

哲学天空的博客 832

立创开源4G+GPS定位系统:基于微信小程序的低成本低功耗追踪方案

本文介绍了一个基于立创开源平台的超小型4G+GPS定位系统方案。该方案采用28mm*28mm主板,集成4G Cat.1通信与GPS定位,通过微信小程序“点灯专家”实现远程追踪管理,具备低成本、低功耗、易于部署的特点,适用于电动车、宠物、资产追踪等多种场景。

weixin_28895791的博客 393

OceanBase容量统计:租户、数据库、表大小

🍎 数据库版本:OceanBase V4。

Sebastien23的博客 1396

tolua++ 编译 及使用 简单介绍 标签: tolua++luaC++

tolua++ 编译 及使用 简单介绍 标签: tolua++luaC++ 2015-11-03 00:52 1576人阅读 评论(0) 收藏 举报  分类: Lua(6)  版权声明:本文转自http://blog.youkuaiyun.com/huutu 转载请带上 http://www.thisisgame.com.cn tolua++ 是用来

boshuzhang的专栏 1714

基于UC3842的反激电源的全面深入解析与MATLAB仿真

内置电流检测,可实现电流模式控制,提高系统的动态响应性。多种保护功能,如欠压锁定、过温保护、短路保护等,确保系统的安全可靠运行。宽工作电压范围,适应不同的电源设计需求。简单的外部元件配置,易于实现。UC3842的典型应用包括开关电源、DC-DC转换器和反激式电源等,其稳定性和可靠性在实际应用中得到了广泛验证。

qq_38334677的博客 1086

tolua++实现分析

项目正在使用cocos2dx的lua绑定,绑定的方式是tolua++。对大规模使用lua代码信心不是很足,花了一些时间阅读tolua++的代码,希望对绑定实现的了解,有助于项目对lua代码的把控。从阅读结果上来看,起码在内存管理上,帮助还是很大的。 1.tolua++如何将c++对象导入到lua里 tolua++为每一个传入lua的对象建立一个userdata,userdata的值,是

wtyqm的专栏 2万+

计算机组成原理(第三版)唐朔飞-第十章控制单元的设计-课后习题

计算机组成原理(第三版)唐朔飞-第十章控制单元的设计-课后习题

weixin_45735391的博客 3万+

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

上一篇: Running LuaJIT
下一篇: 把C++静态库lib封装到Lua解释器中
CoderAldrich
博客等级 码龄12年 431粉丝 24原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值