1

私は、Luaを使用して個々のユニット(アリ)の動作を駆動し、Luabindを使用してC++側とLua側を接着する小さなシミュレーションプロジェクトに取り組んでいます。個々のant(基本クラスAntから派生したさまざまなタイプがあります)には、適切なスクリプトを呼び出すRun()関数があります。次に、スクリプトは、実行する必要のあるアクションを実行し、公開されたクラス関数と、場合によってはフリー関数を呼び出します。Run関数(C ++)を取得して、Luaスクリプトで一致するRun関数を正常に実行しました(現時点ではテキストを出力するだけです)。

void AntQueen::Run()
{
    lua->GetObject("QueenRun")(GetID());
}

luaスクリプトから関数を取得する単なるマネージャークラスです。上記はLuaファイルで以下を呼び出しています:

function QueenRun(ID)
    print("The Queen is running!")
    print(ID)
end

また、Luabindの登録は、AntQueenクラスでは次のようになります。

void Register(lua_State *luaState)
{
    using namespace luabind;
    module(luaState)
    [
        class_<AntQueen, Ant>("AntQueen")
        .def("Eat", &AntQueen::Eat)
        .def("ExtractLarvae", &AntQueen::ExtractLarvae)
        .def("GetMaxLarvaeProduced", &AntQueen::GetMaxLarvaeProduced)
        .def("GetNumAvailLarvae", &AntQueen::GetNumAvailLarvae)
    ];
}

現在の設定方法では、アリは単純なファクトリ/マネージャを介して作成、削除、および検出されます。static Ant* AntFactory::GetAntByID(const int ID)各アリは、ハッシュマップでアリを見つけてアリへのポインタを返す呼び出しによって取得できます。私がやろうとしているのは、Luaに次のようなことができるようにすることです。

function QueenRun(ID)
    ant = GetAntByID(ID)
    larvae = ant:GetNumAvailLarvae()
    print(larvae)
    ant:Eat()
end

上記は単なる例ですが、うまくいけば、私が達成しようとしていることを示しています。オブジェクトはすでにC++側で管理されているため、Luaがオブジェクトをガベージコレクションすることは望ましくありません。すべてをテストしている間、次のことを実行しようとします。

ant = GetAntByID(ID)

Luaabort()で呼び出され、プログラムがクラッシュして焼けてしまいました。

R6010
-abort() has been called

すべてが行き来する方法に何かが欠けているようです(これは、おもちゃのプログラムを超えてLuaとC ++を接着するための私の最初の試みです)。プレーンポインタを渡すことはそれを行う方法ではないと確信しています。lightuserdataは私が探しているもののようですが、多くの制限もあります。

要約すると、ここで何が起こっているabortのか、Luabind / Lua C APIを使用して、Luaに渡されたC ++オブジェクトへのポインターを取得し、そのポインターのメンバー関数をオブジェクトであるかのように呼び出すにはどうすればよいですか? (Luaのガベージコレクションを行わせずに)?

4

1 に答える 1

0

この問題の解決策は、AntFactory クラス/メンバー関数が静的であることに関連しているように見えました。これを登録して使用することから切り替えるとすぐに:

//C++

static int AntFactory::CreateAnt(foo, bar)
{}

//Lua

factory:CreateAnt(foo, bar)

インスタンス化されたオブジェクトと、次のような通常のメンバー関数に:

//C++

int AntFactory::CreateAnt(foo, bar)
{}

//Lua

factory:CreateAnt(foo, bar)

すべてがまったく問題なく機能しました(ファクトリをグローバルテーブルにプッシュした後)。この理由は、インスタンス化されていない C++ オブジェクトで静的メンバー関数を呼び出そうとすると、Lua (または Luabind?) が呼び出しを照会するオブジェクトを持てないために失敗するためだと思います。

于 2011-01-11T04:26:55.270 に答える