2009-05-14 10 views
5

Moja sytuacja polega na tym, że używam API Lua (C) do wykonywania skryptu przechowywanego w ciągu znaków. Chciałbym, aby użytkownik mógł zakończyć wykonywanie skryptu (jest to niezbędne, jeśli skrypt zawiera nieskończoną pętlę), jak to zrobić?Jak mogę całkowicie zakończyć wątek Lua?

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

Odpowiedz

7

Możesz użyć haka do wywołania zwrotnego do C za każdym razem, gdy lua wykonuje linię skryptu. W tej funkcji przechwytującej możesz sprawdzić, czy użytkownik chciał wyjść i zadzwonić do lua_error, jeśli tak zrobił.

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

Dziękuję za poświęcony czas. – CiscoIPPhone

+0

Prawdopodobnie chcesz zadzwonić 'luaL_error (L," wiadomość ")' lub nacisnąć coś na stosie Lua przed wywołaniem 'lua_error (L)'. –

+0

Dzięki Alexander, zredagowałem odpowiedź. Masz rację odnośnie pętli jednoliniowych/nieskończonych pętli w kodzie C, przyznaję, że nie zagłębiłem się w złożoność sytuacji. –

8

Haczyk na liniach to za mało. Ten kod jest pojedynczą linią, ale pętle na zawsze:

while true do end 

Musisz ustawić hak licznika instrukcji. Jeśli się nie mylę, to byłoby

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

Chcesz odebrać NUM_INSTRUCTIONS więc nie jest zbyt małe (lub masz narzut wydajności) i nie jest zbyt duża (lub będziesz czekać zbyt długo, aż do zatrzymania).

Aby zapoznać się z powiązaną implementacją Lua, zobacz this library.

Jeśli chcesz dodać więcej ochrony przed niezaufanym kodem Lua, google "lua sandboxing" - to coś więcej niż nieskończona ochrona przed pętlami.

+0

Masz rację. Czy jednak trzeci parametr nie powinien być LUA_MASKCOUNT? Nawet proste instrukcje nie są idealne - na przykład, jeśli kod LUA wyłączy wywołanie długiej funkcji C. Na razie jednak zrobi to dla moich celów, dzięki. – CiscoIPPhone

+0

Tak, przepraszam. Dodałem teraz LUA_MASKCOUNT. –

Powiązane problemy