I'm trying to use function as metatable __index
to achieve more flexibiilty, but it crashed when the returned value is not assigned to some variable in Lua side.
This is the C++ part, it just creates a table variable whose __index
is pointing to a C function, the function just returns a fixed number value:
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 );
}
And this is the Lua code that causes crash:
const char* lua_src =
"a = {}\n"
"setmetatable(a, test_meta)\n"
"a.foo\n";
The code crashed before C function meta_index
is actually called, and it claims a error message attempt to call a string value.
However, if I put the expression a.foo
who triggers meta indexing on the right of assignment, the code finishes with no error and produces expected result:
const char* lua_src =
"a = {}\n"
"setmetatable(a, test_meta)\n"
"bar = a.foo\n"
"print(bar)\n";
It seems Lua treats the foo
in a.foo
and bar = a.foo
as different things, what is the actual rule for it?
The code below does not compile because expressions like a.foo
are not statements in Lua:
a = {}
setmetatable(a, test_meta)
a.foo
The error message is
4: syntax error near <eof>
This string is left on the top of the stack after luaL_loadstring
. Hence the error attempt to call a string value
when you call lua_call
.
Bottom line: always check the return code of luaL_loadstring
and print any error messages.