下面的代码演示了在C++和lua脚本之间传递数据。
首先在C++中创建一个table,添加元素,然后放置到lua的全局表中。在lua脚本中可以使用C++创建的这个表。
然后在脚本中创建一个表,以脚本返回值的方式返回给C++,在C++中可以读取表中的值。
例子代码需要一个args.lua的lua文件,要手工创建,我把它放到了C盘根目录下。
- // cpplua.cpp : Defines the entry point for the console application.
- //
- #include "stdafx.h"
- extern "C"
- {
- #include <lua.h>
- #include <lauxlib.h>
- #include <lualib.h>
- }
- #include <iostream>
- /* args.lua文件的内容
- io.write( "[lua] These args were passed into the script from C/n" );
- for i=1,table.getn(arg) do
- print(i,arg[i])
- end
- io.write("[lua] Script returning data back to C/n")
- local temp = {}
- temp[1]=9
- temp[2]=8
- temp[3]=7
- temp[4]=6
- temp[5]=5
- temp["test1 key"]="test1 value"
- temp[6]="test 6"
- temp["test 99"]=99
- for i,n in pairs(temp)
- do
- print (i,n)
- end
- return temp,9,1
- */
- int _tmain(int argc, _TCHAR* argv[])
- {
- int status;
- // lua_open: 创建一个新的lua环境
- lua_State* state = lua_open();
- // 在state环境上打开标准库,
- // 标准库包括:
- // luaopen_base
- // luaopen_package
- // luaopen_table
- // luaopen_io
- // luaopen_os
- // luaopen_string
- // luaopen_math
- // luaopen_debug
- luaL_openlibs(state); /* open libraries */
- status = luaL_loadfile( state, "c://args.lua" );
- std::cout << "[C++] Passing 'arg' array to script" << std::endl;
- // 创建一个新的表
- lua_newtable( state );
- //
- // set first element "1" to value 45
- //
- // 调用lua的函数,都是通过压栈出栈来完成的
- // 为表执行一个t[k]=v的操作,则需要先将k压栈,再将v压栈,再调用操作函数
- // lua_rawset直接赋值(不触发metamethods方法)。
- // lua_rawset/lua_settable使用:
- // 它从栈中获取参数。以table在栈中的索引作为参数,
- // 并将栈中的key和value出栈。
- // lua_pushnumber函数调用之前,
- // table是在栈顶位置(索引为-1)。index和value入栈之后,
- // table索引变为-3。
- lua_pushnumber( state, 1 );
- lua_pushnumber( state, 45 );
- lua_rawset( state, -3 );
- // set second element "2" to value 99
- lua_pushnumber( state, 2 );
- lua_pushnumber( state, 99 );
- lua_rawset( state, -3 );
- // set the number of elements (index to the last array element)
- // lua_pushliteral压入一个字符串,不需要指定长度
- // 如果lua_pushlstring,则需要指定长度
- lua_pushliteral( state, "n" );
- lua_pushnumber( state, 2 );
- lua_rawset( state, -3 );
- // set the name of the array that the script will access
- // Pops a value from the stack and sets it as the new value of global name.
- // 从栈顶弹出一个值,并将其设置全局变量"arg"的新值。
- lua_setglobal( state, "arg" );
- std::cout << "[C++] Running script" << std::endl;
- int result = 0;
- if (status == 0)
- {
- result = lua_pcall( state, 0, LUA_MULTRET, 0 );
- }
- else
- {
- std::cout << "bad" << std::endl;
- }
- if (result != 0)
- {
- std::cerr << "[C++] script failed" << std::endl;
- }
- std::cout << "[C++] These values were returned from the script" << std::endl;
- // lua_gettop返回栈顶的索引
- // 如果索引为0,则表示栈为空
- while (lua_gettop( state ))
- {
- switch (lua_type( state, lua_gettop( state ) ))
- {
- case LUA_TNUMBER:
- {
- std::cout << "script returned " << lua_tonumber( state, lua_gettop( state ) ) << std::endl;
- break;
- }
- case LUA_TTABLE:
- {
- std::cout << "script returned a table" << std::endl;
- // 简单的遍历表的功能
- // ***好像lua不保存表的元素的添加顺序***
- // 压入第一个键
- lua_pushnil(state); /* 第一个 key */
- int t = -2;
- while (lua_next(state, t) != 0)
- {
- /* 'key' (索引-2) 和 'value' (索引-1) */
- const char* key = "unknown";
- const char* value;
- if(lua_type(state, -2) == LUA_TSTRING)
- {
- key = lua_tostring(state, -2);
- value = lua_tostring(state, -1);
- }
- else if(lua_type(state, -2) == LUA_TNUMBER)
- {
- // 因为lua_tostring会更改栈上的元素,
- // 所以不能直接在key上进行lua_tostring
- // 因此,复制一个key,压入栈顶,进行lua_tostring
- lua_pushvalue(state, -2);
- key = lua_tostring(state, -1);
- lua_pop(state, 1);
- value = lua_tostring(state, -1);
- }
- else
- {
- value = lua_tostring(state, -1);
- }
- std::cout <<"key="<< key
- << ", value=" << value << std::endl;
- /* 移除 'value' ;保留 'key' 做下一次迭代 */
- lua_pop(state, 1);
- }
- break;
- }
- case LUA_TSTRING:
- {
- std::cout << "script returned " << lua_tostring( state, lua_gettop( state ) ) << std::endl;
- break;
- }
- case LUA_TBOOLEAN:
- {
- std::cout << "script returned " << lua_toboolean( state, lua_gettop( state ) ) << std::endl;
- break;
- }
- default:
- std::cout << "script returned unknown param" << std::endl;
- break;
- }
- lua_pop( state, 1 );
- }
- lua_close( state );
- return 0;
- }
本例用了一个控制台工程,输出如下:
[C++] Passing 'arg' array to script
[C++] Running script
[lua] These args were passed into the script from C
1 45
2 99
[lua] Script returning data back to C
1 9
2 8
3 7
4 6
5 5
6 test 6
test 99 99
test1 key test1 value
[C++] These values were returned from the script
script returned 1
script returned 9
script returned a table
key=1, value=9
key=2, value=8
key=3, value=7
key=4, value=6
key=5, value=5
key=6, value=test 6
key=test 99, value=99
key=test1 key, value=test1 value