Lua调用c模块
一、lua调用c模块总结
1.c函数库成为lua的一个模块
主要做法:将包含c函数的代码生成库文件 linux下是.so windows下是.dll
同时拷贝到lua运行环境的bin下(由于我用的是LuaTool运行环境 所以放在bin下 程序运行默认从bin下找)
这样lua解析器才可以找到.dll文件
2.编写c模块
(1)先编写需要注册的c函数 这些c函数用统一的声明并且必须写为static 返回置为int
(2)定义luaL_Reg结构体 这个结构体数组用来因为注册到Lua模块中
luaL_Reg结构体的第一个字段为字符串 在注册时通知lua该函数的名字
第二个字段为函数指针
最后一个永远为NULL 用来标记结尾
(3) __declspec(dllexport)将函数、类等声明为导出函数,供其它程序调用,作为动态库的对外接口函数、类等
这个函数非常重要 如果没有 将来生成的.dll不能够被lua模块找到
(4)向lua中注册上述的表格
(5)C相关的API
typedef struct lua_State lua_State lua解释器
typedef int (*lua_CFunction)(lua_State *L) 能够别Lua调用的C函数必须是这种规则 函数的返回值int值表示C函数返回值的个数
void lua_pushcclosure(lua_State*L,lua_CFunction fn ,int n) 将一个C必包压栈 fn C函数指针 n 函数关联的upvalue的个数 首先将upvalues依次压栈 然后调用该函数 将C函数压栈 并将n个upvalues出栈
void lua_pushcfunction(lua_State*L,lua_CFunction fn )将c函数压栈 接收一个c函数的指针 然后将Lua.function类型的对象压栈
void lua_register(lua_State*L,const char *name, lua_CFunction f) 注册C函数为一个全局变量
void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup);
注册函数到栈顶的表中;
参数l:luaL_Reg列表,记录了要注册的函数信息,注意,该列表以{NULL, NULL}结尾;
nup参数:upvalue的个数,如果不为0,则注册的所有函数都共享这些upvalues;
先将table压栈,然后将upvalues依次压栈,然后调用该函数进行函数注册。注册完毕后upvalues会出栈。
注意:luaL_register函数已经不再使用,取而代之的是luaL_setfuncs,因为该函数不会创建全局变量。
举例如下 mycomplib.c
从C value —> lua Value 并不是简单地将值通过栈传给lua 而是将其封装成一个table 其中会放生 栈顶新分配元素 绑定或者赋值
一个c value入栈就是进入了lua的世界, lua会生成一个对应的结构并管理起来, 从此就不再依赖这个c value
mycomplib.c
#include <stdio.h> #include <stdlib.h> #include <lua.h> #include <lualib.h> #include <lauxlib.h> static int add(lua_State* L) { double op1 = luaL_checknumber(L,1); double op2 = luaL_checknumber(L,2); lua_pushnumber(L,op1 + op2); return 1; } static luaL_Reg mylibs[] = { {"add",add}, {NULL,NULL} }; // __declspec(dllexport); int luaopen_mycomplib(lua_State* L) { const char *libName = "mycomplib"; luaL_register(L, libName, mylibs); return 1; }
test_c.lua
mycomplib=require "mycomplib" function help() print("you maybe input: lua [script] -d filename1 -f filename2") end function main() aaa=mycomplib.add(10,10) print(aaa) --print(mycomplib.add(10,20)) end main()
编译SO文件
gcc -c -fPIC -o mycomplib.o -I /usr/include/lua5.1/ mycomplib.c gcc -shared -o mycomplib.so mycomplib.o
总结。
对于__declspec这个函数。在测试中。好像并没有感觉到他的意义