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表中

 

posted @ 2014-11-29 19:14  再高一点  阅读(2514)  评论(0编辑  收藏  举报