Lua - pcall with "entry point"(Lua中的pcall函数和“入口点”)

我正在使用以下代码加载Lua脚本:

lua_State * L = lua_open();
luaL_openlibs(L);

const char lua_script[] = "function sum(a, b) return a+b; end print(\"_lua_\")";
int load_stat = luaL_loadbuffer(L,lua_script,strlen(lua_script),lua_script);
lua_pcall(L, 0, 0, 0);

现在我可以调用

lua_getglobal(L,"sum");

并从C端获得结果

但是,当我调用'lua_pcall'时,脚本被执行并导致向控制台输出'_lua_'。如果在通过'lua_getglobal'设置“入口点”函数之前不调用'lua_pcall',我不能后来访问'lua_getglobal'的返回值。有没有办法解决这个问题?我不想在通过'lua_getglobal'设置“入口点”函数之前调用'lua_pcall'。

点赞
用户107090
用户107090

函数 sum 在运行脚本之前没有定义,因为在 Lua 中,函数定义是一种赋值操作,需要将其执行。

因此,无法避免运行定义 sum 的脚本。这就是 lua_pcall 的作用。你可以使用 lua_call,但这样就无法处理错误。

2017-04-13 20:41:30
用户805875
用户805875

如果你可以修改脚本,那么另一种方法是将初始化代码(包括 print 和其他相关代码)封装在一个独立的函数中,像这样:

lua_State * L = lua_open();
luaL_openlibs(L);

const char lua_script[] = "function sum(a,b) return a+b end return function() print'_lua_' end";
int load_stat = luaL_loadbuffer(L,lua_script,strlen(lua_script),lua_script);
lua_pcall(L, 0, 1, 0); // 运行字符串,定义函数…
// 同时将返回的初始化函数放在堆栈上,你可以将其留在原地,或者在其它位置保存以备将来使用,等等...
   /* 其它代码 */
   lua_getglobal(L, "sum");
   lua_pushinteger( L, 2 );
   lua_pushinteger( L, 3 );
   lua_pcall(L, 2, 1, 0);
   printf( "2+3=%d\n", lua_tointeger(L,-1) );
   lua_pop(L, 1);
   /* 其它代码 (保持堆栈平衡!) */
// 然后运行初始化代码:
lua_pcall(L, 0, 0, 0); // 输出 "_lua_"

现在,虽然你仍然需要运行代码块来定义此函数,但是其他初始化代码已经被封装在返回的函数中,你可以在以后的时间 / 修改的环境中运行它(如果在你的情况下不需要,那么也可以不运行)。

2017-04-14 01:13:58