Lua使用介绍 C++调用Lua脚本

2017-04-10 21:20:00
admin
原创 2991
摘要:Lua使用介绍 C++调用Lua脚本

一、Lua使用介绍

1、胶水语言是扩展编译型语言动态执行能力的脚本语言;

2、C++的胶水语言是Lua,Java的胶水语言是Groovy;

3、官方网址:https://www.lua.org

4、帮助文档https://www.lua.org/manual/5.4/

5、下载地址https://luabinaries.sourceforge.net

6、免费IDE:https://studio.zerobrane.com


使用详解:

1、lua注释以--开头;

2、lua.h提供低层次交互,lauxlib.h提供高层次交互,lauxlib.h函数以luaL_开头;

3、lua和c++通信约定,所有lua中的值由lua管理,c++中产生的值lua不知道;

4、lua和c++通信靠虚拟栈,栈先进后出,索引是正数或负数,正数索引1表示栈底,负数索引-1表示栈顶;

5、nil、boolean、number、light userdata这些类型数据直接存放在栈,垃圾回收无关;
6、string、closure、thread、tableuserdata在栈上存放指针,生命周期结束后被垃圾回收;


数据类型:

1、nil,空对象

2、boolean,false和nil使条件为false,其他为true;
3、number:支持整数和浮点数,默认都是64-bit;
4、string,function,thread;

5、table,表示数组和字典,数组下标1开始,提供语法糖tb.key和tb["key"];
6、userdata,允许任意c++数据存储在lua变量;


栈操作函数:

1、int lua_gettop (lua_State *L),获取栈顶索引,零表示空栈;

2、void lua_settop (lua_State *L, int index),设置栈顶索引,零表示清空堆栈,大于当前栈顶将插入空对象;

3、void lua_pushvalue(lua_State *L, int index),栈顶插入指定索引的元素,如果是指针则浅复制;

4、void lua_insert(lua_State *L, int index),在指定索引插入栈顶的元素,原来元素往后移动;

5、void lua_replace(lua_State *L, int index),在指定索引替换为栈顶的元素;

6、void lua_remove(lua_State *L, int index),指定索引清除元素;

7、栈操作代码示例:luastack.cpp


int main(int argc, char **argv)
{
    lua_State *state = luaL_newstate();
    if (state == NULL)
        return EXIT_FAILURE;

    // init stack
    lua_pushstring(state, "I am so cool~");
    lua_pushnumber(state, 666);
    if (lua_isstring(state, 1))
        printf("%s\n", lua_tostring(state, 1));
    if (lua_isnumber(state, 2))
        printf("%.0f\n", lua_tonumber(state, 2));

    // push table
    lua_createtable(state, 0, 0);
    printf("stack top index is %d.\n", lua_gettop(state));
    // set table.age
    lua_pushnumber(state, 888);
    printf("stack top index is %d.\n", lua_gettop(state));
    lua_setfield(state, -2, "age");
    printf("stack top index is %d.\n\n", lua_gettop(state));
    
    // copy table ptr, and change value
    lua_pushvalue(state, -1);
    lua_pushnumber(state, 999);
    lua_setfield(state, -3, "age");
    // view value
    lua_getfield(state, 3, "age");
    printf("%.0f\n", lua_tonumber(state, -1));
    lua_getfield(state, 4, "age");
    printf("%.0f\n", lua_tonumber(state, -1));
    printf("stack top index is %d.\n\n", lua_gettop(state));

    // insert element in stack
    lua_insert(state, 4);
    printf("is table %d.\n", lua_istable(state, 5));
    printf("is number %d.\n", lua_isnumber(state, 6));
    printf("stack top index is %d.\n\n", lua_gettop(state));

    // replace
    lua_replace(state, 5);
    printf("is number %d.\n", lua_isnumber(state, 5));
    printf("stack top index is %d.\n\n", lua_gettop(state));

    // remove stack element
    lua_remove(state, -1);
    printf("stack top index is %d.\n", lua_gettop(state));

    lua_close(state);
    return EXIT_SUCCESS;
}


二、C++调用Lua脚本

调用代码示例:demo.lualuacall.cpp


lua代码:

str = "I am so cool"
tbl = {name = "king", id = 10001}
function add(a,b)
    return a + b
end


c++代码:

int main(int argc, char **argv)
{
    string str;
    lua_State *state = luaL_newstate();
    if (state == NULL)
        return EXIT_FAILURE;

    int ret = luaL_loadfile(state, "demo.lua");
    if (ret)
    {
        printf("load file error.\n");
        goto out;
    }

    //int nargs, int nresults, int errfunc
    ret = lua_pcall(state, 0, 0, 0);
    if (ret)
    {
        printf("pcall error.\n");
        goto out;
    }

    lua_getglobal(state, "str");
    str = lua_tostring(state, -1);
    printf("str = %s.\n", str.c_str());
    printf("stack top index is %d.\n\n", lua_gettop(state));

    lua_getglobal(state, "tbl");
    lua_getfield(state, -1, "name");
    str = lua_tostring(state, -1);
    printf("tbl.name = %s.\n", str.c_str());
    printf("stack top index is %d.\n\n", lua_gettop(state));

    lua_getglobal(state, "add");
    lua_pushnumber(state, 10);
    lua_pushnumber(state, 20);
    printf("stack top index is %d.\n", lua_gettop(state));
    ret= lua_pcall(state, 2, 1, 0);
    printf("stack top index is %d.\n", lua_gettop(state));
    if (ret)
    {
        const char *errMsg = lua_tostring(state, -1);
        printf("%s.\n", errMsg);
        goto out;
    }
    if (lua_isnumber(state, -1))
    {
        double fv = lua_tonumber(state, -1);
        printf("result is %.2f.\n", fv);
    }

out:
    lua_close(state);
    return EXIT_SUCCESS;
}

发表评论
评论通过审核之后才会显示。