胶水语言 Lua交互示例 C++调用Lua脚本

2017-04-10 21:20:00
admin
原创 2496
摘要:胶水语言 Lua交互示例 C++调用Lua脚本

一、胶水语言

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

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

3、Java的胶水语言是Groovy;

4、胶水语言适合做软件插件,因为检查限制较少,不适合做规则引擎


二、Lua5.1交互示例

官方网站http://www.lua.org/

下载地址http://luaforge.net/projects/luaforwindows/

帮助文档http://www.lua.org/manual/5.1/


1)Lua和C通信约定:

Lua和C通信时有这样的约定: 所有的lua中的值由lua来管理, c++中产生的值lua不知道


2)lua的8种基本数据类型(注释以--开头):

nil:空对象

boolean:true或者false,nil和false使条件false,其它为true。
number:双精度浮点数,可以配置为其它类型。(3 3.0 3.1416 314.16e-2 0.31416E1 0xff 0x56)
string:可以是单引号也可以是双引号
function
userdata:允许任意C数据存储在lua变量。
thread
table:用来表示数组、表、集合等,此外提供语法糖tb.key和tb['key'],数组下标1开始。


3)lua.h提供低层次交互,lauxlib.h提供高层次交互(且函数都以luaL_开头)。


4)Lua和C/C++语言通信的主要方法是一个无处不在的虚拟栈,栈的特点是先进后出。

Lua堆栈就是一个struct,堆栈索引的方式可是是正数也可以是负数,区别是:正数索引1永远表示栈底,负数索引-1永远表示栈顶。

1 lua中number, boolean, nil, light userdata四种类型的值是直接存在栈上元素里的, 和垃圾回收无关。
2 lua中string, table, closure, userdata, thread存在栈上元素里的只是指针, 他们都会在生命周期结束后被垃圾回收。


5)常用栈操作函数

int lua_gettop (lua_State *L); //获取栈顶索引,0表示空栈

void lua_settop (lua_State *L, int index); //设置栈顶索引,0表示清空堆栈,大于当前栈顶将插入nil

void lua_pushvalue(lua_State *L, int index); //复制栈上的元素到栈顶,如果是指针则浅复制,top + 1

void lua_remove(lua_State *L, int index); //清除栈上元素,top - 1

void lua_insert(lua_State *L, int index); //栈上指定位置插入元素,top不变

void lua_replace(lua_State *L, int index); //栈上替换元素,top - 1


6 栈操作代码示例 luastack.cpp

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>

using namespace std;

extern "C" {
#include <lua.h>
#include <lauxlib.h>
};

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, 3);
    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, 9);
    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, 6);
    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));

out:
    lua_close(state);
#ifdef _MSC_VER
    getchar();
#endif
    return EXIT_SUCCESS;
}


输出:

I am so cool~
3
stack top index is 3.
stack top index is 4.
stack top index is 3.

6
6
stack top index is 6.

is table 1.
is number 1.
stack top index is 6.

is number 1.
stack top index is 5.

stack top index is 4.


三、C++调用Lua文件

代码下载:luademo.cpp demo.lua


lua代码:

str = "I am so cool"
tbl = {name = "shun", id = 20114442}

function add(a,b)
    return a + b
end


C++代码:

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>

using namespace std;

extern "C" {
#include <lua.h>
#include <lauxlib.h>
};

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);
#ifdef _MSC_VER
    getchar();
#endif
    return EXIT_SUCCESS;
}


输出:

str = I am so cool.
stack top index is 1.

tbl.name = shun.
stack top index is 3.

stack top index is 6.
stack top index is 4.
result is 30.00.

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