ToLua原理和使用教程

Tolua是用来实现C++程序中的类、变量、函数等绑定到lua程序中。绑定后lua代码可以直接调用C++程序中的类、变量、函数等等。

Tolua原理

Tolua做了哪些事

要想知道tolua原理,先了解tolua到底做了些什么事。先看一下下面“lua实现get/set方法”的例子。这个例子包含了三个文件luaBind.cpp文件、Main.cpp文件、a.lua文件。

luaBind.cpp文件

extern "C" {
#include "lua\lua.h"
#include "lua\lualib.h"
#include "lua\lauxlib.h"
}const char *HandlesGetSet = "HandlesGetSet";extern double a /*= 166*/;
int a_get(lua_State*L)
{lua_pushnumber(L, a);return 1;
}int a_set(lua_State *L)
{if (lua_isnumber(L, 1)){a = lua_tonumber(L, 1);}return 0;
}int index_event(lua_State*L)
{//从 registry  中获取变量的get set 方法luaL_getmetatable(L, HandlesGetSet);lua_pushvalue(L, 2);lua_rawget(L, -2);if (lua_isnil(L, -1))// 没有get set方法{lua_pop(L, 2);lua_rawget(L, -2);}else{lua_pushstring(L, "get");lua_rawget(L, -2);lua_pcall(L, 0, 1, 0);//调用get方法}return 1;
}int newindex_event(lua_State *L)
{//从 registry  中获取变量的get set 方法luaL_getmetatable(L, HandlesGetSet);lua_pushvalue(L, 2);lua_rawget(L, -2);if (lua_isnil(L, -1))// 没有get set方法{lua_pop(L, 2);lua_rawset(L, -3);}else{lua_pushstring(L, "set");//调用set方法lua_rawget(L, -2);lua_pushvalue(L, 3);lua_pcall(L, 1, 0, 0);}return 0;
}void BindLua(lua_State *L)
{//获取 _G表
#if defined (LUA_VERSION_NUM) && LUA_VERSION_NUM >= 502 /* after lua 5.2 */lua_pushvalue(L, LUA_REGISTRYINDEX); /* registry */lua_pushnumber(L, LUA_RIDX_GLOBALS); /* registry globalsindex */lua_rawget(L, -2);                  /* registry registry[globalsindex] */lua_remove(L, -2);                  /* registry */
#elselua_pushvalue(L, LUA_GLOBALSINDEX);
#endif//创建 _G表的元表lua_newtable(L);lua_pushstring(L, "__index");lua_pushcfunction(L, index_event);lua_rawset(L, -3);lua_pushstring(L, "__newindex");lua_pushcfunction(L, newindex_event);lua_rawset(L, -3);lua_setmetatable(L, -2);//设置 _G表的元表lua_pop(L, 1);//创建一张表存储在 registry  中luaL_newmetatable(L, HandlesGetSet);//注册 a 变量的get set方法lua_pushstring(L, "a");lua_newtable(L);lua_pushstring(L, "get");lua_pushcfunction(L, a_get);lua_rawset(L, -3);lua_pushstring(L, "set");lua_pushcfunction(L, a_set);lua_rawset(L, -3);lua_rawset(L, -3);lua_pop(L, 1);
}

Main.cpp文件

#include<iostream>
extern "C" {
#include "lua\lua.h"
#include "lua\lualib.h"
#include "lua\lauxlib.h"
}using namespace std;
double a = 166;void BindLua(lua_State *L);
int main()
{lua_State *L = luaL_newstate();luaL_openlibs(L);BindLua(L);a = 99;if (0 != luaL_dofile(L, "a.lua")){printf("%s\n", lua_tostring(L, -1));}printf("a = %f\n\n\n", a);a = a+1000;if (0 != luaL_dofile(L, "a.lua")){printf("%s\n", lua_tostring(L, -1));}printf("a = %f\n", a);lua_close(L);return 0;
}

a.lua文件

print(a)
a = a+1
print("c=", c)
b = "adas"
print("b=", b)

这个个例子实现了将C++程序中的double a变量绑定到了lua程序中。在C++程序中改变了变量a的值,lua程序中可以获取改变后的值,同样lua程序中对变量a赋值后,C++程序也可以获取赋值后的值,具体原理参见:Lua任意类型的get/set方法, 

三个文件的作用如下。

luaBind.cpp文件:  实现将变量double a 绑定到lua程序中

Main.cpp文件: C程序代码

a.lua文件:lua程序代码

可以看到为了绑定double a变量,luaBind.cpp中的代码并不少。为了简化这种绑定,我们可以使用tolua来实现绑定。Tolua可以帮我们生成luaBind.cpp文件,我们只需要将生成后的文件加入到程序中即可完成绑定。

如何生成lua绑定文件

要生成绑定文件,首先我们需要一个tolua++.exe的程序,然后还需要一个.pkg文件。.pkg文件是一个代码文件,代码格式与C++类似。我们首先需要编写一个pkg文件,有了这个文件之后,然后使用tolua++程序对pkg程序进行转换,转换后就就会生成相应的绑定文件。具体操作,请看后续文章。

Tolua使用

Tulua官网http://webserver2.tecgraf.puc-rio.br/~celes/tolua/,更新到tolua-5.2.4,支持lua5.2.4。官网只提供了tolua的源代码,没有提供任何程序。

下载代码解压后,在src目录下有三个目录,如下:

Bin目录中包含了生成tolua++.exe转换程序的代码,我以使用VS2015编译,文章最后有下载地址。

Lib目录包含了程序使用tolua时需要包含的库的代码,因为代码比较少,我一般直接将lib文件夹中的代码直接包含到程序中。

Tests目录包含了tolua的一些例子,这些例子我以全部使用VS2015进行了编译,文章最后有下载地址。

VS2015编译tolua++.exe程序

在Bin目录下有两个.c文件,tolua.c、toluabind.c,将这两个文件加入到项目中,另外项目中还须要lua5.2.4代码和Lib目录下的代码。如下:

编写pkg文件

pkg文件语法,这里不讲解,具体情况tolua官网:http://webserver2.tecgraf.puc-rio.br/~celes/tolua/tolua-3.2.html。语法规则不多,与C++非常接近,很容易看懂。

这里编写一个绑定double a变量的方法。

Bindlua.pkg文件

$extern double a;

double a;

生成绑定文件

Tolua++.exe支持的命令参数。

执行以下命令生成绑定文件。

使用绑定文件

将生成的绑定文件Bindlua.cpp添加到项目中,另外还需要添加tolua源代码src/lib目录下的文件到项目中。如下:

更多有关tolua的例子请参见官方的例子,官方提供我已经转换成VS2015项目,文章结尾由相应的下载地址。

补充:

文中的代码,以及提到到tolua学习资源下载地址:https://pan.baidu.com/s/1boWtfw7

ToLua原理和使用教程相关推荐

  1. 《数据库技术原理与应用教程》一3-5信息世界与逻辑模型

    本节书摘来华章计算机<数据库技术原理与应用教程>一书中的第3章 ,第3.5节,徐洁磐 操凤萍 编著更多章节内容可以访问云栖社区"华章计算机"公众号查看. 3-5信息世界 ...

  2. 网络工程原理与实践教程实验安排

    <网络工程原理与实践教程(第3版)>胜在超凡实验指导书和教材合为一体,"易学,易教,内容新"  第10章 实    验.... 235 实验1 水晶头的制作... 23 ...

  3. 《数据库技术原理与应用教程(第2版)》——习 题 1

    本节书摘来自华章计算机<数据库技术原理与应用教程(第2版)>一书中的第1章,习 题 1,作者 徐洁磐 操凤萍,更多章节内容可以访问云栖社区"华章计算机"公众号查看. 习 ...

  4. 《数据库技术原理与应用教程第2版》——3.6计算机世界与物理模型

    本节书摘来自华章出版社<数据库技术原理与应用教程第2版>一书中的第3章,第3.6节,作者 徐洁磐 操凤萍 ,更多章节内容可以访问云栖社区"华章计算机"公众号查看. 3. ...

  5. 《数据库技术原理与应用教程(第2版)》——第3章 数据管理中的数据模型 3.1 数据模型的基本概念...

    本节书摘来自华章计算机<数据库技术原理与应用教程(第2版)>一书中的第3章,第3.1节,作者 徐洁磐 操凤萍,更多章节内容可以访问云栖社区"华章计算机"公众号查看. 第 ...

  6. 我的世界红石计算机教程1,《我的世界》红石电脑制作原理及使用教程

    原标题:<我的世界>红石电脑制作原理及使用教程 <我的世界>中的红石可以说是非常好玩的要素,很多玩家就做一些红石小装置就满足了,那么下面小编为大家带来的这个红石设施,绝对让各位 ...

  7. c语言链表单值化,《编译原理及实践教程》第3章词法分析.ppt

    <编译原理及实践教程>第3章词法分析 方法如下: 正规式R?有穷自动机NFA M ? s,t是正规式,相应NFA为N(s),N(t),则正规式R=s|t,构造NFA(R) 为: ? 对应正 ...

  8. 《数据库系统原理及应用教程》(苗雪兰等,第五版) 实验五:数据库的组合查询和统计查询实验

    阅读前注意: 1. 本实验报告配套<数据库系统原理及应用教程>(苗雪兰等,第五版) 实验五:数据库的组合查询和统计查询实验(书上10.4节以及第六章部分内容),书本中采用Microsoft ...

  9. 【数据库原理及应用教程(第4版|微课版)陈志泊】【第三章习题】

    文章目录 一.选择题 二.填空题 三.设计题 四.简答题 Reference 一.选择题 1 2 3 4 5 6 7 8 9 10 B A C B C C B D A D 11 12 13 14 15 ...

最新文章

  1. 利用Python让你的命令行像坤坤一样会打篮球
  2. Spring 已经实现的线程池
  3. PHP设计模式之:单例模式
  4. 优先级队列 c语言,使用最小堆使用优先级队列(c语言版本)
  5. 程序员编程必备名言佳句,提升装逼指数~
  6. SQL SERVER作业的Schedules浅析
  7. ActiveMQ消息回流
  8. 从毕业生当中看人与人的差距
  9. 网络规划设计师水平考试备考资料(6.光纤相关)
  10. Unity与UE4引擎源码内使用到的第三方库的比较
  11. 接口测试之用例设计技巧
  12. 《数解道法》(一)前言
  13. java面试题(精选版)
  14. 人工智能革命:从ANI到AGI的道路
  15. 网站分析11——成本控制类指标
  16. 斯坦福ner python_斯坦福大学Corenlp和Java入门(Python程序员)
  17. 统计cassandra单表数据量
  18. 腾讯云服务器申请SSL证书, 配置Nginx, 实现HTTPS
  19. HM5080E带平衡功能、5V USB输入8.4V/1.5A两节锂电池充电芯片
  20. 互联网巨头的自白:那些年,救我于水火的投资人

热门文章

  1. 一分钟了解“matlab得到自然常数e”
  2. 实时时间(24小时制)
  3. 智慧农业管理系统应用
  4. golang数据结构初探之动态数组slice
  5. 毕业设计-模拟数据集生成笔记
  6. 转区系统开放艾欧尼亚转入服务器,LOL转区系统申请客户端及操作流程介绍
  7. 基于python的多因子分析
  8. word论文排版插件_推荐一款强大的Word插件,一键搞定上万字论文的排版问题
  9. Flex布局:Flex布局
  10. 关于win10系统重启后图标自动排序问题的解决方案