LUA5.1调用C函数

1.5k 词

Lua利用一个虚拟的栈(stack)来给C传递值或从C获取值。每当Lua调用C函数,都会获得一个新的栈,该栈初始包含所有的调用C函数所需要的参数值(Lua传给C函数的调用实参),并且C函数执行完毕后,会把返回值压入这个栈(Lua从中拿到C函数调用结果)
本文展示了如何在lua中调用c函数的一种方法:通过将c函数编译成库文件(如Linux的.so),成为Lua的模块

luaclib.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <lauxlib.h>
#include <lualib.h>
#include <stdio.h>
#include <string.h>
static int (lua_State* L)
{
double op1 = luaL_checknumber(L,1);
double op2 = luaL_checknumber(L,2);
lua_pushnumber(L, op1 + op2);
printf("test add!!!rn");
return 1;
}
static int lua_sub(lua_State* L)
{
double op1 = luaL_checknumber(L,1);
double op2 = luaL_checknumber(L,2);
lua_pushnumber(L, op1 - op2);
printf("test sub!!!rn");
return 1;
}
// 该数组元素类型为lauL_Reg结构,该结构有两个字段,一个字符串和一个函数指针
// 结构体数组中的最后一个元素的两个字段均为NULL,用于提示Lua注册函数已经到达数组的末尾。
static const struct luaL_Reg libt_reg[] = {
{"add", lua_add},
{"sub", lua_sub},
{NULL,NULL}
};
// 该C库的唯一入口函数
// luaopen_xxx 与 lua 中 require 对应 例如testlibs_libtt 对应
// require "testlibs.libtt" 即目录testlibs下的libtt.so
// 生成.so 时文件名应取为libtt.so 即 gcc luaclib.c -fPIC -shared -o libtt.so
int luaopen_testlibs_libtt(lua_State *L)
{
luaL_register(L, "ct", libt_reg); // 根据给定的名称(ct)创建或服用一个table,并用数组libt_reg中的信息填充这个table.在luaL_register返回时会将这个table留在栈中
return 1; // 最后,luaopen_testlibs_libtt函数返回1,表示将这个table返回给Lua
}

lua中如何调用:

1
2
3
4
5
require "testlibs.libtt"
print(ct.add(1,2)) -- ct 对应 luaL_register 中第二个参数libname即上面的"ct" ; add 对应上面 libt_reg中的string类型的函数名
-- or
local c = require "testlibs.libtt"
print(c.sub(7,3))

参考:https://www.cnblogs.com/sifenkesi/p/3876745.html
http://www.lua.org/pil/26.2.htm