3

Lua スクリプトを定期的に実行するアプリケーションがあります。スクリプト内で、いくつかのパラメーターをチェックし、Lua スクリプトを続行するか終了するかを決定するために、カスタムの登録済み Lua 関数を作成することがあります。ロジックは理想的にはスクリプトの一部であってはならず、Lua スクリプトを使用してこれを回避することを考えることができますが、アプリケーションを終了せずに Lua スクリプトの実行を停止できるかどうか疑問に思っています。

Delphi で記述され、Lua 5.1 を使用して Lua スクリプトに公開されたカスタム関数があります。Lua スクリプトは次のようになり、Lua のスクリプトは を使用して開始されluaL_loadbufferます。

io.write("Script starting\n");
--Custom Function
ExitIfFound();
io.write("Script continuing\n");

私のカスタム関数は次のようになります。以下にlua_error、スクリプトを停止するために使用しようとした試みの1つを提供します...

function ExitIfFound(LuaState: TLuaState): Integer;
var
  s: AnsiString;
begin
  s := 'ExitIfFound ending script, next Lua script line not called';
  lua_pushstring(LuaState, PAnsiString(s));
  lua_error(LuaState);
end;

カスタム関数が呼び出されたとき、それ以上評価せずに Lua スクリプトを終了する方法がわかりません。setjmpLua に言及し、C でandを使用している投稿を見たことがありlongjmpますが、これらが Delphi をどのように翻訳するのか興味があります。

上記の例では、 を使用するlua_errorと、プログラム全体がクラッシュし、Windows は通常の動作を行い[luarun.exe has stopped working]ます...

これらすべてを踏まえて、私はまだ Lua を Delphi に統合するのにかなり慣れていないので、探索するためのよりクリーンなオプションを見つけられることを願っています。

4

1 に答える 1

1

Lua スクリプトを完全に中止するクリーンな方法はありません。このlua_error関数は、エラーを通知する正しい方法です。エラーをキャッチして次の呼び出し元に伝えるのは、呼び出し元の責任です。

呼び出し元の協力に頼ることができない場合は、デバッグ フックをインストールして、より多くの制御を試みることができます。次に、スクリプトの実行を続行する前に、ホスト プログラムが参照されます。ただし、スクリプトはエラーをキャッチするために使用することで終了を回避できます。pcall

プログラムのクラッシュは、単にエラーを設定したことが原因ではない可能性があります。むしろ、関数で間違った呼び出し規則を使用している可能性がありますExitIfFound。これは cdecl である必要がありますが、他に何も指定しない場合、Delphi のデフォルトは register です。間違った呼び出し規則を使用すると、予測できないパラメーター値が得られ、スタックが破損する可能性があります。関数を型キャストしたり、@を呼び出したときに演算子を使用したりした場合lua_register、コンパイラの型チェッカーから呼び出し規約の不一致を隠している可能性があります。

C++ としてコンパイルlua_errorすると、 の代わりに例外が使用されますlongjmpが、どちらの方法でも、呼び出し元は常にエラーをキャッチします。ただし、Delphi コードで のようなコンパイラ管理型や-ブロックstringのような例外に敏感な構造を使用する場合、例外は重要です。C モードでは、前の への呼び出しによって設定されたウェイポイントに直接ジャンプする を呼び出します。そのジャンプは、Delphi コンパイラがブロックの実行と文字列のクリーンアップを確実にするために設定するような例外ハンドラをスキップします。tryfinallylua_errorlongjmpsetjmpfinally

さらなる頭痛の種は、関数を終了するときにコンパイラが文字列をクリーンアップするため、Lua スタックに置いたポインタが使用されるまでに有効でなくなる可能性があることです。lua_pushstringこれは、引数のコピーを作成するかどうかによって異なります。

于 2012-11-29T00:12:48.803 に答える