问题表现
lua_State *L = lua_open(); /* opens Lua */
luaopen_base(L); /* opens the basic library */
luaopen_table(L); /* opens the table library */
luaopen_io(L); /* opens the I/O library */ <---- 这里出错。
luaopen_string(L); /* opens the string lib. */
luaopen_math(L); /* opens the math lib. */
以上 C++ 代码调用 Lua C 库时,运行时提示:
PANIC: unprotected error in call to Lua API (no calling environment)
原因
Lua 5.1 API 变化。
“The luaopen_* functions (to open libraries) cannot be called directly,
like a regular C function. They must be called through Lua, like a Lua
function.”
http://lua-users.org/lists/lua-l/2007-04/msg00383.html
http://www.lua.org/manual/5.1/manual.html#7.3
解决办法
法一:简单粗暴
改成
lua_State *L = lua_open(); /* opens Lua */
luaL_openlibs(L);
此法一口气加载了很多常用库,做测试环境合适。但是会额外加载一些当次测试可能不需要的库。
法二:真正等价的改法
这个是真正的等价改法。
也就是这种用法:
luaopen_table(L);
应该改成:
lua_pushcfunction(L, luaopen_table);
lua_pushliteral(L, LUA_TABLIBNAME);
lua_call(L, 1, 0);
// 或者
lua_pushcfunction(L,luaopen_table);
lua_call(L,0,0);
lua_pushliteral 里面用的变量在 lualib.h 可查:
Function | Name
----------------+-----------------
luaopen_base | ""
luaopen_table | LUA_TABLIBNAME
luaopen_io | LUA_IOLIBNAME
luaopen_os | LUA_OSLIBNAME
luaopen_string | LUA_STRLIBNAME
luaopen_math | LUA_MATHLIBNAME
luaopen_debug | LUA_DBLIBNAME
luaopen_package | LUA_LOADLIBNAME