// main.cc // C++ 从 Lua 中获取变量的值. 在 Lua 5.1.4-45 测试通过.
#include <iostream>
#include <string>
using namespace std;
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
#pragma comment(lib, "lua5.1.lib") // 这个是 Debug 版. //#pragma comment(lib, "lua51.lib") // 这个是 Release 版.
int main(int argc, char* argv[])
{
/************ Init ************/
const string filename = "c:\\users\\songdeming\\main.lua";
lua_State *luaState = luaL_newstate(); // 创建 Lua 状态. 其实就是一个数据结构.
luaL_openlibs(luaState); // 加载所有标准库, 例如: print 等.
if (luaL_loadfile(luaState, filename.c_str()) // 加载文件. 个人认为是将文件编译, 然后加载到内存.
|| lua_pcall(luaState, 0, 0, 0)) // 执行全部指令. 这一步必须要进行, 目的是获取 Lua
{ // 程序的变量信息, 此后才能通过 getglobal 在栈上定位
cerr <<lua_tostring(luaState, -1) <<endl; // 变量.
lua_pop(luaState, 1);
return -1;
}
/************ Variable ************/
cout <<'\t' <<"Get variables..." <<endl;
lua_getglobal(luaState, "a");
cout <<lua_tonumber(luaState, -1) <<endl;
lua_getglobal(luaState, "b");
cout <<lua_tostring(luaState, -1) <<endl; // 这里返回的是字符串的地址, 因此不要修改字符串, 也不要在弹出栈后访问这个地址. /************ Table ************/
cout <<endl <<'\t' <<"Get table fields..." <<endl;
lua_getglobal(luaState, "t");
lua_pushnumber(luaState, 1); // 获得无名称字段. 即 t[1]
lua_gettable(luaState, -2); // 从 table 中获取值的 index 是 -2.
cout <<lua_tostring(luaState, -1) <<endl;
lua_pop(luaState, 1);
lua_pushstring(luaState, "z"); // 获得有名字段. 即 t['z']
lua_gettable(luaState, -2); // 从 table 中获取值的 index 是 -2.
cout <<lua_tostring(luaState, -1) <<endl;
lua_pop(luaState, 1);
lua_pop(luaState, 1); // 将 table 出栈.
/************ Function ************/
cout <<endl <<'\t' <<"Run function and Get return values..." <<endl; // 获取并执行函数.
lua_getglobal(luaState, "foo"); // 首先在栈中定位函数.
lua_pushnumber(luaState, 999); // 从左向右将参数压栈.
lua_pushstring(luaState, "zzz");
const int paramNum = 2, // 参数数量.
retNum = 2; // 返回值数量.
if (lua_pcall(luaState, paramNum, retNum, NULL) != 0)// 执行函数. lua_pcall(状态指针, 参数个数, 返回值个数, 出错处理函数). 成功返回 0.
{
cerr <<lua_tostring(luaState, -1) <<endl;
lua_pop(luaState, 1);
return -1;
}
// 获得返回值.
// 返回值的压栈顺序是从左向右依次压栈. 第一个参数最早入栈.
for (int i = 1; i <= retNum; ++i)
{
int type = lua_type(luaState, i);
switch (type)
{
case LUA_TNUMBER:
cout <<"LUA_TNUMBER: " <<lua_tonumber(luaState, i) <<endl;
break;
case LUA_TSTRING:
cout <<"LUA_TSTRING: " <<lua_tolstring(luaState, i, NULL) <<endl;
break;
case LUA_TBOOLEAN:
cout <<"LUA_TBOOLEAN: " <<boolalpha <<lua_toboolean(luaState, i) <<endl;
break;
default :
cout <<"unknown: " <<lua_typename(luaState, type) <<endl;
break;
}//switch
}//for
// 将返回值出栈.
lua_settop(luaState, -retNum);
// TODO: Fetch table returned from function.
/************ Close *************/
lua_close(luaState);
return 0;
}
-- main.lua -- Lua 作为配置文件.
-- 变量不能设为 local.
-- Varaibles.
a = 123
b = 'xyz'
-- Table.
t = {345, 'hello', z = 'uvw'}
-- Function.
function foo(x, y)
print('foo()', x, y)
return 1, 'abc' -- TODO: return {...}
end
总结来说, 从 C++ 中获得 Lua 的值, 需要如下 4 步:
1) [必须] lua_getglobal 定位到栈中的变量.
2) [可选] lua_pushnumber/lua_pushstring 设置需要取得哪个字段.
3) [必须] lua_tonumber/lua_tostring 获得结果.
4) [可选] 如果之前有过 lua_pushxxx 操作, 则需要手工 lua_pop.
|
请发表评论