当元表 __index 指向函数并且未使用返回值时 Lua 崩溃
Posted
技术标签:
【中文标题】当元表 __index 指向函数并且未使用返回值时 Lua 崩溃【英文标题】:Lua crashed when metatable __index pointing to a function and returned value is not used 【发布时间】:2021-09-11 14:28:45 【问题描述】:我正在尝试将函数用作元表__index
以实现更大的灵活性,但是当返回的值未分配给 Lua 端的某个变量时它崩溃了。
这是C++部分,它只是创建了一个表变量,其__index
指向一个C函数,该函数只是返回一个固定的数值:
int meta_index( lua_State* lua )
juce::Logger::writeToLog( "meta_index with key " + juce::String( lua_tostring( lua, 2 ) ) );
lua_pushnumber( lua, 123.456 );
return 1;
int main()
lua_State* lua = luaL_newstate();
luaL_openlibs( lua );
// create a table with __index slot
lua_createtable( lua, 0, 0 );
lua_pushstring( lua, "__index" );
lua_pushcfunction( lua, meta_index );
lua_settable( lua, -3 );
lua_setglobal( lua, "test_meta" );
// run lua code
luaL_loadstring( lua, lua_src );
lua_call( lua, 0, 0 );
lua_close( lua );
这是导致崩溃的 Lua 代码:
const char* lua_src =
"a = \n"
"setmetatable(a, test_meta)\n"
"a.foo\n";
代码崩溃之前 C 函数meta_index
实际被调用,并声称错误消息尝试调用字符串值。
但是,如果我将触发元索引的表达式a.foo
放在赋值右侧,则代码完成时不会出现错误并产生预期的结果:
const char* lua_src =
"a = \n"
"setmetatable(a, test_meta)\n"
"bar = a.foo\n"
"print(bar)\n";
Lua 似乎将a.foo
和bar = a.foo
中的foo
视为不同的东西,它的实际规则是什么?
【问题讨论】:
【参考方案1】:下面的代码无法编译,因为像a.foo
这样的表达式在 Lua 中不是语句:
a =
setmetatable(a, test_meta)
a.foo
错误信息是
4: syntax error near <eof>
此字符串在luaL_loadstring
之后留在堆栈顶部。因此,当您调用 lua_call
时会出现错误 attempt to call a string value
。
底线:始终检查luaL_loadstring
的返回码并打印任何错误消息。
【讨论】:
以上是关于当元表 __index 指向函数并且未使用返回值时 Lua 崩溃的主要内容,如果未能解决你的问题,请参考以下文章