2009-05-14 3 views
5

私の状況は、文字列で保持されているスクリプトを実行するためにLua(C)APIを使用しているということです。 スクリプトの実行を終了できるようにしたいと思います(スクリプトに無限ループが含まれている場合は必須です)。どうすればいいですか?ルアスレッドをきれいに終了できますか?

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

答えて

7

luaがスクリプトの行を実行するたびにフックを使用してCにコールバックすることができます。 このフック関数では、ユーザが終了したいかどうかを確認し、終了した場合はlua_errorを呼び出すことができます。

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

ありがとうございます。 – CiscoIPPhone

+0

おそらく 'luaLerror(L、" message ")'を呼び出すか、 'lua_error(L)'を呼び出す前に何かをLuaスタックにプッシュする必要があります。 –

+0

ありがとうアレクサンダー、私は答えを編集しました。 Cコードの単一行ループ/無限ループについては正しいですが、私は状況の複雑さを掘り下げませんでした。 –

8

フック・オン・ラインでは不十分です。このコードは1行ですが、永遠にループします。

while true do end 

命令カウントフックを設定する必要があります。私は間違っていない場合は、それはそれは小さすぎないようにするには、NUM_INSTRUCTIONSを選択します(またはパフォーマンスのオーバーヘッドを取得)

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

こととあまり大きくない(またはあなたが停止するまであまりにも長い間待っていますでしょう)。

関連するLuaのみの実装については、this libraryを参照してください。

信頼できないLuaコードから保護を追加する場合は、「Luaサンドボックス」についてgoogleを実行してください。無限ループ防止よりも多くのことがあります。

+0

あなたは正しいです。 LUA_MASKCOUNTは3番目のパラメータではありませんか?命令だけでは理想的ではありません。たとえば、Luaコードが消えた場合、長いC関数が呼び出されます。しかし、それは私の目的のために今、感謝のために行います。 – CiscoIPPhone

+0

はい、申し訳ありません。私は今LUA_MASKCOUNTを追加しました。 –

関連する問題