2

lua をゲーム エンジンに埋め込もうとしています。今まではすべてうまくいきました。ゲーム エンジン (例: move_object(id, x, y)) とやり取りする関数の登録を開始しましたが、登録は正常に機能しました。次に、次のように使用してみました。

handlers={}

handlers["update"] = function(objId)
--  print(objId)
    move_object(objId, 0, 0)
end

これにより、luabind から「実行時エラー」例外が発生します。どこでも検索しましたが、インターネット (および luabind ソース) によると、エラー メッセージはまだ lua スタックの一番上にあるはずです。luabind::error をキャッチして、スタックの一番上を次のように出力してみました。

std::cout << "error: lua: " << lua_tostring(exc.state(), -1) << std::endl;

そしてこのように:

std::cout << "error: lua: " << luabind::object(luabind::from_stack(exc.state(), -1)) << std::endl

両方ともこれを印刷します:

error: lua: update

これは、ハンドラー テーブルから更新関数を呼び出したときにプッシュされた最後の値であると想定しています。この値は、エラーが発生したときに、詳細なエラー文字列で上書きされているはずですよね? luabind ソース ファイル "error.hpp" によると、次の定義がありclass errorます。

// this exception usually means that the lua function you called
// from C++ failed with an error code. You will have to
// read the error code from the top of the lua stack
// the reason why this exception class doesn't contain
// the message itself is that std::string's copy constructor
// may throw, if the copy constructor of an exception that is
// being thrown throws another exception, terminate will be called
// and the entire application is killed.

私の lua コードの問題は、実際には move_object 関数の登録にあると思います (更新関数が実行されます。以前にその print 呼び出しのコメントを外したので、これはわかっています)。ハハハ

それが助けになるなら、私はエラーを修正しました。次のように move_object 関数を定義していました。

luabind::module(m_L)[
    luabind::def("move_object", &ScriptEntityManager::move_object)
];

しかしどうやら、静的メンバ関数を luabind で通常の関数として定義することはできません。これを次のように変更しました ( move_objectC++ で通常のグローバル関数を作成しました)。

luabind::module(m_L)[
    luabind::def("move_object", move_object)
];

それが元の問題に役立つかどうかはわかりませんが、より多くの情報が害になることはないと思いました! :)

4

1 に答える 1

2

また、luabind 例外をキャッチするときに、エラー メッセージの値が正しくありません。luabind (set_pcall_callback) で使用されるエラー ハンドラを設定して、例外がスローされる前に発生するエラー (およびコールスタック) を出力することで、問題を解決しました。そのように私にとってはうまくいきます。

しかし、例外をキャッチするときにスタックの一番上にエラーメッセージが含まれていない理由を誰かが実際に知っているなら、私も興味があります:-)

誰かを助けることができる場合に使用するエラーハンドラーを次に示します (「print」は、std::string をログに記録できるカスタム関数です)。

int luabindErrorHandler( lua_State* L )
{
    // log the error message
    luabind::object msg( luabind::from_stack( L, -1 ) );
    std::ostringstream str;
    str << "lua> run-time error: " << msg;
    print( str.str() );

    // log the callstack
    std::string traceback = luabind::call_function<std::string>( luabind::globals(L)["debug"]["traceback"] );
    traceback = std::string( "lua> " ) + traceback;
    print( traceback.c_str() );

    // return unmodified error object
    return 1;
}
于 2013-01-05T22:14:53.127 に答える