3

しばらくの間、Lua でクラッシュの問題が発生していましたが、最終的に何が問題であると思われるかを発見しました。便宜上、呼び出そうとする関数をスクリプトで省略できるようにしています。アプリケーションで TestFun の呼び出しを試行し (例として)、存在する場合はそれを実行し、存在しない場合は正常にサイレントに失敗します。

私が抱えていた問題は、単に lua_pcall(L, 0, 0, 0) を呼び出し、戻り値を無視したことでした。私が発見したのは、Lua が "attempt to call nil" というエラーを生成すると、これをスタックに配置し、これをポップしていないことでした。以下のコードは、スタックサイズが大きくなりすぎたために、実行直後にクラッシュします。

int _tmain(int argc, _TCHAR* argv[])
{
    std::string script = "";
    lua_State* L = luaL_newstate();
    luaL_openlibs(L);
    luaL_loadstring(L, script.c_str());
    lua_pcall(L, 0, LUA_MULTRET, 0);

    while (true)
    {
        lua_getglobal(L, "TestFunc");
        lua_pcall(L, 0, 0, 0);
    }

    return 0;
}

while ループ内のコードを次のように変更しただけです。

while (true)
{
    lua_getglobal(L, "TestFunc");
    if (lua_pcall(L, 0, 0, 0))
        lua_pop(L, -1);
}

そして、これは私のクラッシュを解決しました。私の質問は、これが lua_pcall() エラー結果のすべてのケースで有効かどうか、または -1 をポップする必要があるかどうかを特にチェックしないことで別のバグ/クラッシュに備えているかどうかです (またはおそらく他のもの?)。おそらく、-1 が文字列の場合にのみポップする必要がありますか、それとも、呼び出すことができる標準の「スタックをクリーンアップする」関数があるのでしょうか?

ありがとう

4

1 に答える 1

3

-1ではなく1をポップする必要があることを除いて、変更されたコードは問題ありません。

于 2013-07-08T15:57:38.117 に答える