C++ << Lua (C++ 调用 Lua)

// 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.

 

posted @ 2012-07-23 16:43  walfud  阅读(3292)  评论(1编辑  收藏  举报