马上面临毕业设计,打算做点跟网游有关的,先从做周边工具开始,目前正在做一个协议序列化和反序列化的东西,广告一波先: https://github.com/Anti-Magic/rproto

目前非常简陋,功能还没做完,不要当真。。

因为目标是绑定到lua,作为一个独立的库,不想对项目有依赖,这样的好处是客户端和服务端都可以方便的拿来用,所以打算手动绑定。

我夜观天象发现,到目前为止网上找不到针对lua5.3的这么简明扼要且完整的示例,转载注明出处:http://www.cnblogs.com/wolfred7464/p/5147675.html

由于lua提供的require函数可以引入C语言的动态链接库,对于使用者来说,不需配置,只要调用require就可以,肯定是最简单的方法。(其实iOS不能这样做的,唉,习惯就好)

首先读者需要对lua提供的操作虚拟栈的函数比较熟悉,不熟悉的先翻手册吧:http://cloudwu.github.io/lua53doc/manual.html

先上一段简单的示例,功能是使用C语言编写一个计算2个浮点数之和的add函数,绑定到lua由lua调用:

 #include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
#include "luaconf.h" double add(double x, double y) {
return x+y;
} static int ladd(lua_State* L) {
double x = luaL_checknumber(L, );
double y = luaL_checknumber(L, );
lua_pushnumber(L, add(x+y));
return ;
} int luaopen_xxx(lua_State* L) {
luaL_checkversion(L); struct luaL_Reg funcs[] = {
{"add", ladd},
{NULL, NULL}
};
luaL_newlib(L, funcs);
return ;
}

在linux使用gcc编译:

gcc main.c -shared -fPIC -I/usr/local/include -o xxx.so

lua的package.cpath中需要能搜索到我们的so,设置cpath的方法网上搜一下有很多。然后lua代码中这样调用:

 local xxx = require "xxx"
print(xxx.add(, ))

最后在终端执行:

lua test.lua

这个例子就跑起来了,虽然步骤说不上多简单,但是足够清晰吧。。为了简单,我就不写检查参数数量和类型是否匹配的代码了,后面的例子也是。

如何使用lua调用C++呢?只要你会操作userdata,基本上照搬上面的C语言的方式就可以,只不过显式传递C++的this指针就可以。再上一个简单的代码:

 #include <lua.hpp>

 class TTT {
public:
TTT() {}
~TTT() {} double add(double x, double y) {
return x+y;
}
}; extern "C"
{
static int lnewTTT(lua_State* L) {
TTT** p = (TTT**)lua_newuserdata(L, sizeof(TTT*));
*p = new TTT();
return ;
} static int ldelTTT(lua_State* L) {
TTT** p = (TTT**)lua_topointer(L, );
delete *p;
*p = nullptr;
return ;
} static int ladd(lua_State* L) {
TTT** p = (TTT**)lua_topointer(L, );
TTT* pt = *p;
lua_pushnumber(L, pt->add(lua_tonumber(L, ), lua_tonumber(L, )));
return ;
} int luaopen_xxx(lua_State* L) {
luaL_checkversion(L);
luaL_openlibs(L); struct luaL_Reg funcs[] = {
{"new", lnewTTT},
{"add", ladd},
{"del", ldelTTT},
{NULL, NULL}
};
luaL_newlib(L, funcs);
return ;
}
}
 local xxx = require "xxx"
local t = xxx.new()
print(xxx.add(t, , ))
xxx.del(t)

(为什么要使用指针的指针呢?因为lua申请内存和释放内存时不会调用C++的构造函数和析构函数,我们又不能手动去调用,只能使用指针的指针,便于手动调用构造和析构函数了。)

使用lua的userdata保存this指针,然后作为参数传递到绑定函数,然后C语言就可以调用了,第一个例子明白后,这个没什么难度。

但是这样做有三个问题:一是无法检查lua传来的this指针是否是正确的类型,二是需要手动释放内存,三是lua代码中调用起来太麻烦。

这三个问题有一个共同的解决方案:元表(metatable)。

1、给同一类userdata设置同一个元表,利用元表就可以区别不同类型的userdata。

2、lua垃圾回收时会调用元表中的"__gc"元方法,我们可以利用这个元方法析构C++对象。

3、索引字段会调用"__index"方法,不存在这个方法时会从元表中查找,利用这个特性我们可以把red.add(t, x, y)这样的调用变成t.add(t, x, y),然后就可以写成t:add(x, y)了。

把第二个例子中的lnewTTT和luaopen_xxx两个函数修改一下就可以,上代码:

 static int lnewTTT(lua_State* L) {
TTT** p = (TTT**)lua_newuserdata(L, sizeof(TTT*));
*p = new TTT();
luaL_getmetatable(L, "xxx.TTT");
lua_setmetatable(L, -);
return ;
} int luaopen_xxx(lua_State* L) {
luaL_checkversion(L);
luaL_openlibs(L); struct luaL_Reg funcs[] = {
{"new", lnewTTT},
{NULL, NULL}
}; struct luaL_Reg funcs_meta[] = {
{"add", ladd},
{NULL, NULL}
}; luaL_newmetatable(L, "xxx.TTT");
lua_pushstring(L, "__gc");
lua_pushcfunction(L, ldelTTT);
lua_settable(L, -);
lua_pushstring(L, "__index");
lua_pushvalue(L, -);
lua_settable(L, -);
luaL_setfuncs(L, funcs_meta, );
luaL_newlib(L, funcs);
return ;
}
 local xxx = require "xxx"
local t = xxx.new()
print(t:add(, ))

基本上就是这样了,绑定其他的数据类型,或者保存上下文等,都可以查找手册解决,lua天生为了嵌入宿主语言而设计,与C语言的交互有天然的优势。

lua5.3调用C/C++的更多相关文章

  1. 黑马毕向东Java基础知识总结

    Java基础知识总结(超级经典) 转自:百度文库 黑马毕向东JAVA基础总结笔记    侵删! 写代码: 1,明确需求.我要做什么? 2,分析思路.我要怎么做?1,2,3. 3,确定步骤.每一个思路部 ...

  2. 《果壳中的C# C# 5.0 权威指南》 - 学习笔记

    <果壳中的C# C# 5.0 权威指南> ========== ========== ==========[作者] (美) Joseph Albahari (美) Ben Albahari ...

  3. Lua中调用C函数(lua-5.2.3)

    Lua能够调用C函数的能力将极大的提高Lua的可扩展性和可用性. 对于有些和操作系统相关的功能,或者是对效率要求较高的模块,我们全然能够通过C函数来实现,之后再通过Lua调用指定的C函数. 对于那些可 ...

  4. C程序与Lua脚本相互调用

    Lua脚本是一种可用于C程序开发/测试的工具,本篇介绍一下C程序与Lua脚本如何进行相互调用,更加详细的操作参见<Programing in Lua>.本文分为3个部分:1.Windows ...

  5. Win7 64位 VS2013环境编译Lua5.3.1

    主要参考这篇文章,原文有几个错误顺便改正了. 在Windows下使用Visual Studio编译Lua5.3 写本文时Lua官方网站放出的新版本为5.3.1,然后我不知道为啥,神奇的国内不能访问Lu ...

  6. lua如何调用C++函数

    第一步是定义函数.所有在Lua中被调用的C/C++函数将使用下面一类指针进行调用: typedef int (*lua_CFunction) (lua_State *L); 换句话说,函数必须要以Lu ...

  7. vs如何在C++中调用Lua

    最近Cocos2dx的学习卡壳了,一般的照抄代码我不想写上来,但想示例也想得我头晕...为了放松大脑调整状态于是开始学习Lua.Lua的语法学习还是比较简单的,学过javascript或者vbscri ...

  8. vs2013如何在C++中调用Lua(二)

    Lua学习笔记 vs2013如何在C++中调用Lua (此为转载教程) 本人试过完全可行 一.准备工作 1.下载Lua源码,地址:http://www.lua.org/download.html(我用 ...

  9. LUA脚本调用C场景,使用C API访问脚本构造的表

    LUA调用C lua解析中集成了一些系统服务, 故脚本中可以访问系统资源, 例如, lua脚本可以调用文件系统接口, 可以调用数学库, 但是总存在一些lua脚本中访问不到的系统服务或者扩展功能, 如果 ...

随机推荐

  1. javacv

    (看到有很多同学都来看这篇文章,说明可能是有必要的,然后这个写的比较水,所以 如果求干货的话,请移步: http://www.cnblogs.com/letben/p/5885799.html 但是 ...

  2. weblogic服务器内存溢出问题解决

    问题描述: 当我们在weblogic服务器一个域domain上面部署多个工程时,经常会出现内存溢出的情况:java.lang.OutOfMemoryError异常 原因:主要是因为weblogic环境 ...

  3. LAMP平台搭建详解

    准备工作 安装编译工具 # yum -y install gcc # yum -y install gcc-c++ 如果系统之前已经安装有rpm包的mysql和apache,那么可以: #servic ...

  4. 【模拟,时针分针秒针两两夹角】【没有跳坑好兴奋】hdu - 5387 (多校#8 1008)

    算是最好写的一道题了吧,最近模拟没手感,一次过也是很鸡冻o(* ̄▽ ̄*)o 注意事项都在代码里,没有跳坑也不清楚坑点在哪~ #include<cstdio> #include<cst ...

  5. ASP.NET运行原理

    1,ASP.NET运行原理: 客户端向服务器发出请求 → 服务器处理请求→ 处理好的数据以报文发给浏览器 → 浏览器显示请求结果 2,Chrome浏览器,查看请求过程:F12打开浏览器的调试窗口: 3 ...

  6. hiho 1182 : 欧拉路·三

    1182 : 欧拉路·三 这时题目中给的提示: 小Ho:是这样的,每次转动一个区域不是相当于原来数字去掉最左边一位,并在最后加上1或者0么. 于是我考虑对于"XYYY",它转动之后 ...

  7. Android 快捷方式相关操作

    尽管现在少数手机不支持快捷方式,但是仍然有大部分手机是支持的.创建快捷方式,可以减少用户在应用列表繁多的应用程序中查找应用的时间,快速进入应用:或是应用中的某个功能使用频率较高,创建快捷方式,可以快速 ...

  8. sql查询统计,根据新闻类别ID统计,没有数据显示0

    有两张表,新闻信息表MessageInfo和新闻类别表MessageType.表结构如下: 然后需要实现下面这种查询结果: 这个是我面试时遇到的,上面的新闻类型是乱写的.当时没有做出来,然后回来又研究 ...

  9. html保留字符详解

    本文由 www.169it.com 搜集整理 1. 注释 HTML中的注释和其它语言注释作用相似,都是为了方便阅读和调试代码.当浏览器遇到注释时会自动忽略注释内容.HTML的注释格式多行和单行注释都用 ...

  10. eclipse插件hibernate tools安装 爱好者

    eclipse helios(3.6)版 1.启动eclipse 2.选择Help > Install New Software...> 3.添加如下地址:http://download. ...