私は、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のガベージコレクションを行わせずに)?