Lua调用C函数
Lua作为嵌入式语言,主要的优点就是和C语言的相互调用,通过lua调用c函数是非常有用的,通过将c动态库引入,从而能调用c的函数,大大丰富了Lua的开发能力。
Lua调用C函数的方式:
1.Lua能调用C函数,不是说Lua能调用所有的C函数,就像C调用Lua一样,需要遵守一定的协议,Lua只能调用已经注册的C函数,并且也是通过虚拟栈实现的。
2.注册的C函数需要满足的形式:
typedef int (*lua_CFunction) (lua_State *L);
例:
double max(double a, double b){
return a>b ? a:b;
}
static int l_max (lua_State *L) {
double num1 = lua_tonumber(L, 1);
double num2 = lua_tonumber(L, 2);
lua_pushnumber(l, max(num1, num2));
return 1;
}
3.注册成C函数
lua_pushcfunction(L, l_max); lua_setglobal(L, "mymax");
4.Lua中调用(test.lua)
d = mymax(340,37); io.write(d)
完整的C函数
#include"lua.h" #include"lualib.h" #include"lauxlib.h" double max(double a, double b){ return a>b ? a:b; } static int l_max (lua_State *L) { float num1 = lua_tonumber(L, 1); float num2 = lua_tonumber(L, 2); lua_pushnumber(L, max(num1, num2)); return 1; } int main() { lua_State *L = luaL_newstate(); luaL_openlibs(L); lua_pushcfunction(L, l_max); lua_setglobal(L, "mymax"); if (luaL_loadfile(L, "test.lua") || lua_pcall(L, 0, 0, 0)) { printf("%s", lua_tostring(L, -1)); } }
将Lua调用的C函数,写在C中不是好的方式,我们更希望直接通过lua动态包含,这时可以用lua的require函数,加载这些c模块
1.首先我们要将Lua要调用的C函数编译成动态库
1 #include"lua.h" 2 #include"lualib.h" 3 #include"lauxlib.h" 4 5 6 float max(float a, float b){ 7 return a>b ? a:b; 8 } 9 10 static int l_max (lua_State *L) { 11 float num1 = lua_tonumber(L, 1); 12 float num2 = lua_tonumber(L, 2); 13 14 lua_pushnumber(L, max(num1, num2)); 15 return 1; 16 } 17 18 static const struct luaL_Reg mylib [] = { 19 {"max", l_max}, 20 {NULL, NULL} 21 }; 22 23 //入口函数,会被require调用 24 int luaopen_mylib (lua_State *L) { 25 luaL_newlib(L, mylib); 26 return 1; 27 }
这里需要注意到是编译时需动态引入lua库,不能使用静态库,否则会产生 multiple Lua VMs detected 的错误,C程序也要使用lua动态库。
但问题是下载的lua只存在静态库liblua.a,网上的解决方法是修改MakeFile文件产生动态库,可参见http://blog.csdn.net/rheostat/article/details/18796911。
2.lua中的调用(test.lua)
1 a = require "mylib" 2 print(a.max(5, 10))
3.简化后的C程序
#include <stdio.h> #include "lua.h" #include "lualib.h" #include "lauxlib.h" int main() { lua_State *L = luaL_newstate(); luaL_openlibs(L); if (luaL_loadfile(L, "test.lua") || lua_pcall(L, 0, 0, 0)) { printf("%s", lua_tostring(L, -1)); } }
require "*"时,会自动调用动态库中的 luaopen_* 函数,
我是require "mylib",所以动态库中必须有luaopen_mylib函数,该函数通过luaL_newlib(L, mylib)将l_max函数加载到lua表中