Lua 当元表 __index 指向一个函数并且没有使用返回值时崩溃

Lua crashed when metatable __index pointing to a function and returned value is not used

我正在尝试使用函数作为 metatable __index 来实现更多的灵活性,但是当返回值未分配给 Lua 端的某个变量时它崩溃了。

这是C++部分,它只是创建一个table变量,其__index指向一个C函数,函数只是returns一个固定的数值:

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之前,它声称错误消息attempt to call a string value.

但是,如果我将表达式 a.foo who triggers meta indexing 放在赋值的右边,代码将无错误地完成并产生预期的结果:

const char* lua_src =
    "a = {}\n"
    "setmetatable(a, test_meta)\n"
    "bar = a.foo\n"
    "print(bar)\n";

似乎Lua将a.foobar = a.foo中的foo视为不同的东西,它的实际规则是什么?

下面的代码无法编译,因为像 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 的 return 代码并打印任何错误消息。