下面的代碼示範了在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