Lua C API

2015-02-12 15:54  1600人阅读  评论 (0)
Tags: lua

lua5.3

http://lua.org/
http://cloudwu.github.io/lua53doc/

依赖

yum install readline

编译安装

curl -R -O http://www.lua.org/ftp/lua-5.3.0.tar.gz
tar zxf lua-5.3.0.tar.gz
cd lua-5.3.0
make linux test
make install

C扩展

// func.c
#require "lua.h"
#require "lualib.h"
#require "lauxlib.h"

// 加法
static int add(lua_State *L) {
    double a = luaL_checknumber(L, 1); // 获取第一个参数
    double b = luaL_checknumber(L, 2); // 获取第一个参数
    lua_pushnumber(L, a + b); // 计算并返回结果
    return 1;
}

// 减法
static int sub(lua_State *L) {
    double a = luaL_checknumber(L, 1); // 获取第一个参数
    double b = luaL_checknumber(L, 2); // 获取第一个参数
    lua_pushnumber(L, a - b); // 计算并返回结果
    return 1;
}

// 乘法
static int mul(lua_State *L) {
    double a = luaL_checknumber(L, 1); // 获取第一个参数
    double b = luaL_checknumber(L, 2); // 获取第一个参数
    lua_pushnumber(L, a * b); // 计算并返回结果
    return 1;
}

// 除法
static int div(lua_State *L) {
    double a = luaL_checknumber(L, 1); // 获取第一个参数
    double b = luaL_checknumber(L, 2); // 获取第一个参数
    lua_pushnumber(L, a / b); // 计算并返回结果
    return 1;
}

// 函数列表
static const struct luaL_Reg func[] = {
    {"add", add}, // 注册函数
    {"sub", sub},
    {"mul", mul},
    {"div", div},
    {NULL, NULL} // 结尾必须以空结尾
};

// 注册函数 格式为luaopen_包名
int luaopen_func(lua_State *L) {
    luaL_openlib(L, "func", func, 0);
    return 1;
}

编译

gcc -fPIC --shared -o func.so func.c

C调用

#require "lua.h"
#require "lualib.h"
#require "lauxlib.h"

int main()
{
    //Lua示例代码,使用table
    char *szLua_code =
        "x = {} --用于存放结果的table "
        "x[1],x[2] = string.gsub(c.Str, c.Mode, c.Tag) --x[1]里是结果,x[2]里是替换次数 "
        "x.u = string.upper(x[1])";
    //Lua的字符串模式
    char *szMode = "(%w+)%s*=%s*(%w+)";
    //要处理的字符串
    char *szStr = "key1 = value1 key2 = value2";
    //目标字符串模式
    char *szTag = "<%1>%2</%1>";

    lua_State *L = luaL_newstate();
    luaL_openlibs(L);

    //把一个tabele送给Lua
    lua_newtable(L); //新建一个table并压入栈顶
    lua_pushstring(L, "Mode");// key
    lua_pushstring(L, szMode);// value
    //设置newtable[Mode]=szMode
    //由于上面两次压栈,现在table元素排在栈顶往下数第三的位置
    lua_settable(L, -3);
    //lua_settable会自己弹出上面压入的key和value

    lua_pushstring(L, "Tag");// key
    lua_pushstring(L, szTag);// value
    lua_settable(L, -3);    //设置newtable[Tag]=szTag

    lua_pushstring(L, "Str");// key
    lua_pushstring(L, szStr);// value
    lua_settable(L, -3);    //设置newtable[Str]=szStr

    lua_setglobal(L,"c"); //将栈顶元素(newtable)置为Lua中的全局变量c

    //执行
    bool err = luaL_loadbuffer(L, szLua_code, strlen(szLua_code),
                "demo") || lua_pcall(L, 0, 0, 0);
    if(err)
    {
        //如果错误,显示
        cerr << lua_tostring(L, -1);
        //弹出栈顶的这个错误信息
        lua_pop(L, 1);
    }
    else
    {
        //Lua执行后取得全局变量的值
        lua_getglobal(L, "x");

        //这个x应该是个table
        if(lua_istable(L,-1))
        {
            //取得x.u,即x["u"]
            lua_pushstring(L,"u");    //key
            //由于这次压栈,x处于栈顶第二位置
            lua_gettable(L,-2);
            //lua_gettable会弹出上面压入的key,然后把对应的value压入
            //取得数据,然后从栈中弹出这个value
            cout << "x.u = " << lua_tostring(L,-1) << endl;
            lua_pop(L, 1);

            //取得x[1]和x[2]
            for(int i=1; i<=2; i++)
            {
                //除了key是数字外,与上面的没什么区别
                lua_pushnumber(L,i);
                lua_gettable(L,-2);
                cout << "x[" << i <<"] = " << lua_tostring(L,-1) << endl;
                lua_pop(L, 1);
            }
        }

        //弹出栈顶的x
        lua_pop(L, 1);
    }
    lua_close(L);
    return 0;
}

执行lua脚本

#require "lua.h"
#require "lauxlib.h"
#require "lualib.h"

int main(){
    lua_State *L = luaL_newstate();
    luaL_openlibs(L);

    luaL_dofile(L, "test.lua");

    lua_close(L);
    return 0;
}

// gcc -o test test.c -I/usr/local/require -L/usr/local/lib -llua -lm -ldl