2009-05-14 8 views
5

Meine Situation ist, dass ich die Lua (C) API verwenden, um ein Skript in einer Zeichenfolge ausgeführt wird. Ich möchte, dass der Benutzer die Ausführung des Skripts beenden kann (das ist wichtig, wenn das Skript eine Endlosschleife enthält), wie kann ich das tun?Wie kann ich einen Lua-Thread sauber beenden?

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

Antwort

7

können Sie einen Haken verwenden, um C jedes Mal lua eine Zeile des Skripts Rückruf ausführt. In dieser Hook-Funktion können Sie überprüfen, ob der Benutzer beenden wollte, und lua_error aufrufen, falls dies der Fall war.

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

Vielen Dank für Ihre Zeit. – CiscoIPPhone

+0

Sie möchten wahrscheinlich entweder 'luaL_error (L," message ")' aufrufen oder etwas vor dem Aufruf von 'lua_error (L)' auf den Lua-Stack schieben. –

+0

Danke Alexander, ich habe die Antwort bearbeitet. Sie haben Recht, wenn es um einzelne Zeilenschleifen/unendliche Schleifen im C-Code geht. Ich gebe zu, dass ich mich nicht mit den Komplexitäten der Situation befasst habe. –

8

Haken auf Leitungen ist nicht genug. Dieser Code ist eine einzelne Zeile, aber für immer loops:

while true do end 

Sie müssen einen Befehlsanzahl Hook festlegen. Wenn ich mich nicht irre, das wäre

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

Sie wollen NUM_INSTRUCTIONS holen, damit es nicht zu klein ist (oder Sie eine Performance-Overhead zu bekommen) und nicht zu groß (oder Sie zu lange warten, bis zum Anschlag).

Für verwandte Lua-only-Implementierung siehe this library.

Wenn Sie mehr Schutz vor dem nicht vertrauenswürdigen Lua-Code hinzufügen möchten, googlen Sie nach "Lua sandboxing" - da steckt mehr dahinter als nur die Vermeidung von Endlosschleifen.

+0

Sie haben Recht. Sollte der dritte Parameter nicht LUA_MASKCOUNT sein? Selbst Befehle sind nicht ideal - wenn beispielsweise der Lua-Code ausgeht, ruft eine lange C-Funktion auf. Aber es wird für meine Zwecke für jetzt tun, danke. – CiscoIPPhone

+0

Ja, tut mir leid. Ich habe jetzt LUA_MASKCOUNT hinzugefügt. –