Lua采取的是利用栈进行交互,利用各种Lua_pushXXX将不同的值压入栈中,然后调用Lua脚本时自然会退栈取出参数运行,对于Lua的虚拟机来说,就像是发生了一次正常的函数调用。(这里采用的栈是Lua栈,因为若是C栈的话调用Lua的C API就会出错了。)需要注意的是,Lua栈状态需要自己进行维护,若发生多线程同时对Lua栈操作,没有加锁保护的话会导致栈状态混乱然后出很诡异的bug 摘自 多语言协作与二进制交互
函数接口
typedef struct lua_State lua_State;
lua虚拟机(或叫解释器),可以理解为一个thread,和一个完整的Lua虚拟环境的执行状态。
typedef int (*lua_CFunction) (lua_State *L);
能够被Lua调用的C函数都必须是这种规则。函数的返回的int值表示C函数返回值的个数。
void lua_pushcfunction (lua_State *L, lua_CFunction f);
将C函数压栈,接收一个C函数的指针参数,然后将一个Lua.function类型的对象压栈。
void lua_register (lua_State *L, const char *name, lua_CFunction f); // #define lua_register(L,n,f) (lua_pushcfunction(L, f), lua_setglobal(L, n))
注册C函数为一个全局变量;
示例代码
C代码
- 首先接受一个Lua虚拟机变量L,然后从L里取出相应的参数(需要指定数据类型),最后将返回值再次压回虚拟机里面,通过返回int告诉Lua虚拟机,自己的返回值有多少个。
编译成.so
gcc -Wall -shared -fPIC -o power.so -I/usr/include/lua5.1 -llua5.1 hellofunc.c
- shared是告诉gcc,需要编译成.so文件
- -fPIC,是Position Independent Code的意思,具体的含义可以参考这篇,主要用来避免同一份代码因为重定位位置不同而在内存中存在多个实例
lua代码
代码语言:javascript复制require("power")
print(square(1.44))
参考
- 从lua调用C函数
- Lua初学者(四)–Lua调用原理展示(lua的堆栈)
- Lua中调用C函数