swig でラップされ、lua に登録されたクラスがあります。このクラスのインスタンスを lua スクリプトで作成でき、すべて正常に動作します。
しかし、新しい X への呼び出しを使用して C++ コードで作成されたクラスのインスタンスがあり、呼び出したい関数を含む la lua_state L があり、1 つの引数、X のインスタンスを受け入れるとします...その関数を呼び出すにはどうすればよいですか。これが問題のコードの(一部)です(エラー処理のものは省略しました):
main.cpp
class GuiInst;
extern "C"
{
int luaopen_engine (lua_State *L);
}
int main()
{
GuiInst gui=new GuiInst;
lua_State *L=luaL_newstate();
luaopen_engine(L); //this is swigs module
int error=luaL_loadfile(L,"mainmenu.lua")||
lua_pcall(L, 0, 0, 0);
lua_getglobal(L,"Init");
//Somehow push gui onto lua stack...
lua_pcall(L, 1, 0, 0));
lua_close(L);
}
mainmenu.lua
function Init(gui)
vregion=gui:CreateComponent("GuiRegionVertical");
end
現時点で私が見つけたのは、swig で生成された cpp ファイルからいくつかの機能を公開し、それを呼び出すことだけです。これにはいくつかの理由があります...複数のモジュールがある場合は機能せず、swig ファイルのデフォルトのリンケージ仕様を変更する必要がありました (-DSWIGRUNTIME= を使用)。
以下を main.cpp に追加します
extern "C"
{
struct swig_module_info;
struct swig_type_info;
int luaopen_engine (lua_State *L);
swig_module_info *SWIG_Lua_GetModule(lua_State* L);
void SWIG_Lua_NewPointerObj(lua_State* L,void* ptr,swig_type_info *type, int own);
swig_type_info *SWIG_TypeQueryModule(swig_module_info *start,swig_module_info *end,const char *name);
}
//and then to push the value...
SWIG_Lua_NewPointerObj(L,gui,SWIG_TypeQueryModule(SWIG_Lua_GetModule(L),SWIG_Lua_GetModule(L),"GuiInst *"),0);
モジュールへのポインターを取得し、次に型へのポインターを取得し、swigs 関数を呼び出して登録します。人間が読めるはずのないファイルを掘り下げなければならないのは不合理なことでした (そのため、ファイルの上部に記載されています)。(しかし、それは機能します!)
確かに、私がやろうとしていることを達成するためのより良い方法があります。
高レベルの pov からの PS 私が望むのは、GuiInst の Object Factory によって作成された Gui コンポーネントを lua が参照しないようにすることです。いくつかの非常に単純な (そして非 swig) Python モジュールを除いて、スクリプト言語に機能を公開するのはこれが初めてなので、アドバイスを受ける準備ができています。
アドバイスをありがとう!
RBerteig によるコメントへの応答
GuiInst のコンストラクターは、lua がそのインスタンスを構築するのを防ぐために、swig が実行されるときにプライベートに #defined されるため、私にとってはうまくいきません。私が防ごうとしていたのは次のことでした(luaで):
r=engine.GuiRegionVertical()
r:Add(engine.GuiButton())
これは "g=new GuiButton" を呼び出し、GuiRegionVertical (さまざまな理由でポインターを格納する必要があります) に登録し、"delete g" を呼び出します。GuiRegionVertical には g へのポインターがぶら下がったままになります。
本当に必要なことは、GuiRegionVertical::Add(GuiButton*) が GuiButton* の参照カウントをインクリメントし、GuiRegionVertical のデストラクタがすべてのコンテンツの参照カウントをデクリメントすることだと思いますが、これがどのように行われるかはわかりませんスウィグで行われます。
これにより、プライベート コンストラクター、Gui オブジェクト ファクトリ、厄介な外部関数が不要になります。
私はこれについて間違っていますか?
ありがとう。