1 简介
在上节学习了如何编写可以在lua语言中调用的C函数,但是要想使用这个C函数,我们必须在程序中使用lua_register函数进行注册,再重新进行编译.对于另外一种情况就是程序已经编译好,如lua解释器等,要想使用如前面的C_add函数,必须重新修改lua.c的源码重新编译比较麻烦,可以采用这个函数写成C模块方式并编译成动态链接库模式,使用时再采用lua加载模块方式载入。
2 C模块代码
编写C模块代码,并声明一个mylib数组,定义一个luaopen_mylib打开函数,具体如下.
c
//06C模块代码.c
//编译为mylib.dll可以在lua动态载入
#include <stdio.h>
#include <stdlib.h>
// Lua数据类型与函数接口
#include "lua.h"
// Lua与C交互辅助函数接口
#include "lauxlib.h"
// Lua标准库打开接口
#include "lualib.h"
// 定义C函数,与上一节相同
static int C_add( lua_State* L){
printf("使用lua调用C函数C_add成功\n");
//使用lua_tointeger按索引获取栈L的元素
//索引1为函数参数1,2为函数参数2,以此类推.
//lua传递参数给C语言需进行数据转换,
//因为这个函数参数均为整数,所以使用lua_tointeger
//若其他数据类型,需使用类似的lua_to*函数
int a1 = lua_tointeger(L,1);
int a2 = lua_tointeger(L,2);
int a3 = lua_tointeger(L,3);
//打印各个参数的值
printf("第1个参数=%d\n",a1);
printf("第2个参数=%d\n",a2);
printf("第3个参数=%d\n",a3);
//将三个参数值相加并压入栈
//使用lua_pushinteger函数将整数值压入,其他数据类型需使用类似lua_push*函数
//若有多个返回值,按顺序压入栈
lua_pushinteger(L,a1+a2+a3);
// 返回值为lua函数add的返回值数量,为1.
return 1;
}
//声明一个数组,数组元素类型为luaL_Reg,字段分布为{注册函数名字符串,函数指针}
//最后一项必须为{NULL,NULL}
static const struct luaL_Reg mylib[]={
{"add",C_add},
{NULL,NULL}
};
// 定义C模块打开函数
int luaopen_mylib(lua_State *L){
// 对函数 lual_newlib的调用会新创建一个表,
// 并使用由数组 mylib指定的"函数名-函数指针"填充这个新创建的表。
// 当lual_newlib返回时,它把这个新创建的表留在了栈中,在表中它打开了这个库。
luaL_newlib(L,mylib);
//返回1,表示将这个表返回给Lua。
return 1;
}
3 编译C模块
使用需将上诉C模块代码编译为mylib.dll才能使用,在批处理界面输入编译指令如下
c
::编译为动态链接库mylib.dll,编译需用到lua.dll
tcc -shared -rdynamic -I %lua_src% lua.dll 06C模块代码.c -o mylib.dll
4 编写调用C程序
对上一节程序修改如下,在lua语言中动态加载mylib.dll并使用。
c
//07lua中调用C模块
#include <stdio.h>
#include <stdlib.h>
// Lua数据类型与函数接口
#include "lua.h"
// Lua与C交互辅助函数接口
#include "lauxlib.h"
// Lua标准库打开接口
#include "lualib.h"
int main()
{
// 创建Lua状态
lua_State* L = luaL_newstate();
// 打开标准库
luaL_openlibs(L);
// 解析并执行Lua脚本字符串
luaL_dostring(L,"
-- 使用require函数载入C模块mylib
mylib=require('mylib')
-- 调用mylib库中的add函数
a=mylib.add(7,2,5)
print('a=',a) -->14
");
// 关闭Lua线程
lua_close(L);
return 0;
}
运行结果如下
5 在lua解释器中使用C模块
在上面例子中C模块是在lua动态载入,也可以在已编译好的程序中载入该c模块。如我们常用的lua解释器。
先创建一个lua解释器,在批处理窗口输入编译并运行lua解释器
c
::编译lua解释器
tcc -I %lua_src% lua.def %lua_src%\lua.c -o lua.exe
::运行lua解释器
lua
输入下面lua代码即可调用C模块函数
lua
-- 使用require函数载入C模块mylib
mylib=require('mylib')
-- 调用mylib库中的add函数
a=mylib.add(7,2,5)
print('a=',a) -->14
运行结果如下。