Lua 作为一种小巧的语言,一般都是嵌入到 C/C++ 中作为扩展语言,但是也可以作为独立的脚本语言使用,并且可以使用 C/C++ 编写扩展模块。在参考资料 [1] 中有怎样用 C/C++ 编写模块的介绍,但是比较零散,也不是很详细,所以在这里整理一下。

这里使用的 Lua 版本是 5.2.3,系统是 Debian 7。

Hello, world!

不废话,还是先看一下经典的 “Hello, world!” 例子。

luahello.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>static int l_hello(lua_State* l) { printf("Hello, world!\n"); return 0; }   static const struct luaL_Reg hello_lib[] = { {"hello", l_hello}, {NULL, NULL}, };   int luaopen_luahello(lua_State* l) { luaL_newlib(l, hello_lib); return 1; }

这里用到的一个函数是

void luaL_newlib (lua_State *L, const luaL_Reg *l);

它其实是一个宏,被定义为

(luaL_newlibtable(L,l), luaL_setfuncs(L,l,0))

作用是先创建一个新的 table,再把指定的函数注册到这个 table 中。

要注意的是,创建自定义模块的函数都需要以 “luaopen_” 作为函数名的前缀,这样在 require 中加载某个模块(例如这里的模块名叫 “luahello”)的时候,Lua 会去找相应的创建模块的函数(例如 luaopen_luahello),然后调用这个函数,获得对应的返回值,之后就可以被使用了。

另外由于 require 的参数是一个字符串,如果我们写成 “require(‘a.b’)” 也是合法的,但是在 C 语言中无法定义 “luaopen_a.b” 这样一个函数。Lua 很智能地为我们做了转换,将 “.” 转换成 “_”。

编译和执行

先说一下静态加载的方法。

查看 src/Makefile,可以发现 Lua 为我们预留了一些编译变量,例如 MYCFLAGS 和 MYLIBS 等。如果需要解析器能使用我们自己编写的模块,只需把我们的模块加到这些变量中。根据参考资料 [1] 的建议,还需要修改 luaL_openlibs(),把 luaopen_hello() 添加到 loadedlibs[] 这个数组中,让 Lua 解析器调用相应的函数后才能被调用。如果要把上面的模块编译到 Lua 解析器中,可以把 luahello.o 加入到MYOBJS 中:

make posix MYOBJS=`pwd`/luahello.o -C /path/to/lua

重新编译之后就能使用我们自定义的函数了。

可见每增加一个模块就要重新编译一次 Lua 显然是不现实的,因此更好的方法是采用动态加载。

Lua 默认只生成静态链接库 liblua.a,编译 Lua 解析器也是用的静态链接。但是 Lua 的实现中用到了一个全局变量,如果多次链接 liblua.a 会出问题(见参考资料 [2]),因此如果主程序和模块都分别链接了 liblua.a,接着主程序加载了模块运行会导致程序崩溃,需要使用选项 “-Wl,-E” 重新编译 Lua 解析器;为了能加载动态链接库,还需要打开相应的选项,在 Linux 下完整的编译命令为:

make posix MYCFLAGS="-DLUA_USE_DLOPEN -Wl,-E" MYLIBS="-ldl"

重新编译后应该就能正常加载运行脚本了。作为实验封装了一个 MySQL 的 Lua 客户端,放在 这里。

参考资料

[转]使用 C 编写 Lua 模块相关推荐

  1. 如何编写Python模块/包?

    本文翻译自:How to write a Python module/package? I've been making Python scripts for simple tasks at work ...

  2. 第四章 Lua模块开发

    在实际开发中,不可能把所有代码写到一个大而全的lua文件中,需要进行分模块开发:而且模块化是高性能Lua应用的关键.使用require第一次导入模块后,所有Nginx 进程全局共享模块的数据和代码,每 ...

  3. java redis 商品秒杀_redis编写lua脚本实现商品秒杀

    编写lua脚本 --是否秒杀 local hasBuy = redis.call('sismember',KEYS[1],ARGV[1]) if hasBuy~=0 then return 0; en ...

  4. python用什么来写模块-使用C语言编写Python模块-引子【转】

    为什么要用C语言写Python模块,是Python不够香么?还是觉得头发还茂盛?都不是.因为C语言模块有几个显而易见的好处: 可以使用Python调用C标准库.系统调用等; 假设已经有了一堆C代码实现 ...

  5. LuaForUnity6:Lua模块

    一.Lua模块简介 如果不怎么能理解,可以先去学习下Lua的面对对象 为什么需要模块:为了拆分代码,很像命名空间 模块的使用:在A.lua中写好了一些函数,在B.lua中只需加载A.lua,就可以直接 ...

  6. 【react-native】编写原生模块给JS进行交互,一键加群的实现。

    最近一直用RN开发,原生已经小半年没碰过了,需要给Rn的程序加一个一键加群的功能,以往都是用Intent来写,但是RN不支持,查了一下文档,发现有个编写原生模块进行调用的方式,就写了一个加群的模块,很 ...

  7. gg修改器怎么编写lua脚本

    gg修改器怎么编写lua脚本,gg修改器编写Lua脚本的例子 从搜索冻结值的数10.搜索前7次的结果被冻结为8的值. gg.searchNumber('10', gg.TYPE_DWORD)local ...

  8. lua 字符串包含_Programming in Lualua学习第11期 Lua模块与包

    微信公众号:GameToolDev 关注可了解更多的游戏工具开发教程.问题或建议,请公众号留言; 从Lua 5.1开始,我们可以使用require和module函数来获取和创建Lua中的模块.从使用者 ...

  9. 在html中使用thymeleaf编写通用模块

    在编写页面时,常常会需要用到通用模块,比如header部分.footer部分等. 项目前端使用的是themeleaf模板引擎,下面简单介绍下使用themeleaf写header通用模块: 1. 通用部 ...

最新文章

  1. 有关LocalAlloc,LocalReAlloc,LocalFree,GlobalAlloc,GlobalReAlloc,GlobalFree的模糊点总结
  2. golang map 排序 key value
  3. apply plugin: 'idea' --- gradle idea
  4. cocos2dx-lua控制台报错集合
  5. 移植YAFFS2文件系统到linux3.18.4内核(原)
  6. Java黑皮书课后题第3章:*3.8(对三个整数排序)编写程序,提示用户输入三个整数,以非降序的形式显示这三个整数
  7. vue.js 组件之间传递数据 1
  8. MySQL Server Architecture
  9. oracle ko16mswin949,mysql字符集 - osc_wq7ij8li的个人空间 - OSCHINA - 中文开源技术交流社区...
  10. cnpm安装webpack_Webpack(一)介绍
  11. 优化算法笔记|萤火虫算法理解及实现
  12. 诗与远方:无题(七十七)- 远方
  13. 动环监控系统中B接口的实现
  14. recon-ng详细使用教程
  15. 台式机安装EXSI,通过官方方式定制安装包
  16. 数学推导+纯Python实现机器学习算法22:EM算法
  17. airpods pro是按压还是触摸_使用AirPods Pro一个月后,我是这么看待它的
  18. 如何划分测试集和训练集
  19. 大觉寺到鹫峰线路_体验古香道---从大觉寺过鹫峰到妙峰山涧沟村
  20. 同质化竞争格局下,SCRM厂商如何差异化突围?

热门文章

  1. Android判断应用是否拥有某种权限
  2. iOS 自定义 View
  3. (0089)iOS开发之iOS应用间相互跳转(URL Scheme)
  4. java如何保存初始化数据_java – 如何在JUnit测试中初始化数据
  5. 190401装饰器-高阶函数-闭包
  6. Remove Nth Node From End of List - LeetCode
  7. 接口自动化测试的几个阶段
  8. 常见的音视频封装和编码
  9. Appium——unknown error: cannot activate web view
  10. Mac中使用port升级gcc版本