Lua使用介绍 C++调用Lua脚本
- 2017-04-10 21:20:00
- admin
- 原创 2991
一、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、table、userdata在栈上存放指针,生命周期结束后被垃圾回收;
数据类型:
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.lua、luacall.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;
}