2009-05-14 6 views
5

Ma situation est que j'utilise l'API Lua (C) pour exécuter un script contenu dans une chaîne. Je voudrais que l'utilisateur puisse terminer l'exécution du script (ceci est essentiel si le script contient une boucle infinie), comment puis-je faire cela?Comment puis-je terminer un fil Lua proprement?

lua_State *Lua = lua_open(); 
char * code; 
// Initialisation code 
luaL_dostring(L, code); 

Répondre

7

Vous pouvez utiliser un crochet pour rappel à C chaque lua temps exécute une ligne du script. Dans cette fonction de crochet, vous pouvez vérifier si l'utilisateur a voulu quitter, et appeler lua_error si c'est le cas.

static bool ms_quit = false; 

void IWantToQuit() 
{ 
    ms_quit = true; 
} 

void LineHookFunc(lua_State *L, lua_Debug *ar) 
{ 
    if(ar.event == LUA_HOOKLINE) 
     if(ms_quit == true) 
      luaL_error(L, "Too Many Lines Error"); 
} 
//... 

lua_State *Lua = lua_open(); 
char * code; 
// Initialisation code 
lua_sethook(Lua, &LineHookFunc, LUA_MASKLINE, 0); 
luaL_dostring(L, code); 
+0

Nous vous remercions de votre temps. – CiscoIPPhone

+0

Vous voulez probablement appeler 'luaL_error (L," message ")' ou pousser quelque chose sur la pile Lua avant d'appeler 'lua_error (L)'. –

+0

Merci Alexander, j'ai édité la réponse. Vous avez raison en ce qui concerne les boucles à une seule ligne/boucles infinies en code C, je reconnais que je n'ai pas plongé dans les complexités de la situation. –

8

Crochet sur les lignes n'est pas suffisant. Ce code est une ligne unique, mais boucle pour toujours:

while true do end 

Vous devez définir un crochet de compte d'instructions. Si je ne me trompe pas, ce serait

lua_sethook(Lua, &LineHookFunc, LUA_MASKCOUNT, NUM_INSTRUCTIONS); 

Vous voulez choisir NUM_INSTRUCTIONS il est donc pas trop petit (ou si vous obtenez une surcharge de performance) et pas trop grand (ou vous allez attendre trop longtemps jusqu'à l'arrêt).

Pour la mise en œuvre de Lua uniquement, voir this library.

Si vous voulez ajouter plus de protection contre le code Lua non approuvé, google pour "Lua sandboxing" - il n'y a pas que la prévention de boucle infinie.

+0

Vous avez raison. Le troisième paramètre ne devrait-il pas être LUA_MASKCOUNT? Même les instructions ne sont pas idéales - par exemple, si le code Lua se déclenche, une longue fonction C est appelée. Cependant, il fera pour mes fins pour l'instant, merci. – CiscoIPPhone

+0

Oui, désolé. J'ai ajouté LUA_MASKCOUNT maintenant. –