lua调用so动态库

今天,我给我的测试软件框架添加了一个 C 模块,里面封装了一个 sleep 的系统调用。我的目的是在用 Lua 时,要延时的话,不用执行 os.execute("sleep 5") 之类的蹩脚语句,而替之以 mt.sleep(5) 之类的就行了。

我是这样来做到的。

看如下源文件,注意里面的注释。

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>
 
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <limits.h>
 
/*  三个有关 lua 的头文件   */
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
 
/*  库 open 函数的前置声明   */
int luaopen_mt(lua_State *L);
 
 
/*  一个函数功能的实现:对 usleep 做封装   */
/* seconds --
 * interval units -- */
static int mt_sleep(lua_State *L)
{
   lua_Number interval = luaL_checknumber(L, 1);
   lua_Number units = luaL_optnumber(L, 2, 1);
   usleep(1000000 * interval / units);
   return 0;
}
 
/*  将定义的函数名集成到一个结构数组中去,建立 lua 中使用的方法名与 C 的函数名的对应关系   */
static const luaL_reg mt_lib[] = {
   {"sleep", mt_sleep},
   {0,0}
};
 
/*  库打开时的执行函数(相当于这个库的 main 函数),执行完这个函数后, lua 中就可以加载这个 so 库了   */
int luaopen_mt(lua_State *L)
{
   /*  把那个结构体数组注册到 mt (名字可自己取)库中去 */
   luaL_register(L, "mt", mt_lib);
   return 1;
}

C 源代码编辑好后,要编译成动态库。用如下参数编译:
第一步,编译出 .o 文件;

gcc -O2 -Wall -fPIC -W -Waggregate-return -Wcast-align -Wmissing-prototypes -Wnested-externs -Wshadow -Wwrite-strings -pedantic -I /root/apps/luasystem/lua/include/ -c -o mt.o mt.c

第二步,编译出 .so 文件。

gcc -O2 -Wall -fPIC -W -Waggregate-return -Wcast-align -Wmissing-prototypes -Wnested-externs -Wshadow -Wwrite-strings -pedantic -L /root/apps/luasystem/lua/lib/ -shared -o mt.so mt.o -llua5.1

在龙芯上,之前我也试过用用简单的参数来编译,但编译出来的文件用lua加载时出现段错误。所以加上了这么多的参数。

编译出 so 文件后,在 lua 脚本里面,写上

require ‘mt’

后面,就可以使用 sleep 函数了

mt.sleep(5)

到此为止,一个 lua 用的 C 模块就添加完成了,感觉上也不是很难的,模式很固定。只是首先要对 lua 的 C API 有了解才是。
不过,这里面所说的只是建立一个新的模块,然后编译,后面还会讲到如何定义一个新的模块,但里定义的函数的名字空间是先前的模块名(如os, io等)。这对于扩展基础的库功能很有用。后面再讲。

原文
Lua lib 加载分析
Lua 中写 C 扩展库时用到的一些技巧
lua中的require机制
扩展阅读
编写python的C语言扩展
lua data structure same as redis sorted set

标签: lua, c

添加新评论