2 votes

Lua se plante lorsque le metatable __index pointant vers une fonction et la valeur retournée n'est pas utilisée

J'essaie d'utiliser la fonction comme métatable. __index pour obtenir plus de flexibilité, mais il s'est planté lorsque la valeur retournée n'est pas assignée à une variable du côté Lua.

C'est la partie C++, elle crée simplement une variable de table dont le nom est __index pointe vers une fonction C, la fonction renvoie simplement une valeur numérique fixe :

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 );
}

Et voici le code Lua qui provoque le crash :

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

Le code s'est écrasé antes de Fonction C meta_index est effectivement appelé, et il réclame un message d'erreur tentative d'appeler une valeur de type chaîne .

Cependant, si je mets l'expression a.foo qui déclenche la méta indexation à droite de l'affectation, le code se termine sans erreur et produit le résultat attendu :

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

Il semble que Lua traite le foo en a.foo y bar = a.foo comme des choses différentes, quelle est la règle réelle pour cela ?

2voto

lhf Points 30556

Le code ci-dessous ne compile pas car des expressions comme a.foo ne sont pas des déclarations en Lua :

a = {}
setmetatable(a, test_meta)
a.foo

Le message d'erreur est le suivant

4: syntax error near <eof>

Cette chaîne est laissée en haut de la pile après que luaL_loadstring . Par conséquent, l'erreur attempt to call a string value quand vous appelez lua_call .

En résumé, vérifiez toujours le code de retour de l'option luaL_loadstring et imprimez les éventuels messages d'erreur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X