これは実際にはかなり複雑です。 SWIGの予想される使用法は、Lua用のモジュールを作成することです。 Luaスクリプトは、何が呼び出され、何が呼び出されないのかを決定するものでなければなりません。 SWIGを使っていくつかのC++オブジェクトを公開してからアプリケーションから直接Luaコードを呼び出す組み込み用途のためのものではありません。
これは不可能だと言っているのではなく、複雑です。
すべてのSWIGベースのC++オブジェクトは、Luaを介してポインタとして渡されます。したがって、所有権は問題です。スタックオブジェクトへのポインタをLuaに押し込むことはできません。
これを行う最も安全な方法は、オブジェクトの新しいコピーをLuaに渡すことです。そうすれば、Luaはポインタを所有します。 SWIGはLuaがポインタを所有していることを知り、適切なガベージコレクションメカニズムを付けてそれをクリーンアップします。だから、すべてのメモリが賢明でなければならない。
これを行うには、適切な "ボクシング"(より良い用語が必要なため)SWIGが望んでいるようにそのオブジェクトが必要です。これには、特定のSWIGマクロを使用する必要があります。あなたはSWIGにpath
タイプをバインドしているか、あなたがスタックLuaの上にそれを固執するこのような何かをするだろう考える
:
swig_type_info *pathType = SWIG_TypeQuery("boost::filesystem::path *");
boost::filesystem::path *pArg = new boost::filesystem::path(the_path);
SWIG_NewPointerObj(L, pArg, outputType, 1);
SWIG_TypeQuery
がにSWIGに拘束されている任意のオブジェクトの種類をフェッチルアこの型情報オブジェクトは、SWIG_NewPointerObj
に必要であり、その型へのポインタをとります。どちらもマクロです。 SWIG_NewPointerObj
はポインタのLuaの所有権を与えます。 Luaのガベージコレクタは、SWIGのメタテーブルのおかげでそれを削除します。また、SWIG_NewPointerObj
は、オブジェクトをlua_State
スタックにプッシュします。
スタックに入ったら、それを使って何でもできます。それを関数からLuaに返し、それを引数としてLua関数に渡し、グローバル変数にスティックします。これはLuaの値です。
このコードをプロジェクトに入力すると、コンパイラがswig_type_info
と表示されたときにコンパイルエラーが発生する可能性があります。このタイプは、SWIGのコマンドラインで生成されたソースファイル内でと内部的にはと定義されています。
は、2つのオプションがあります。.swigファイル自体にこのソースコードを入れ
。はい、そうです。通常のC++関数を逐語的なセクション内に定義することができます(%{
%}
区切りブロック)。これらの関数はSWIGの生成コードに直接コピーされます。プロトタイプをヘッダーに入れてアクセスできます。これは最も簡単で簡単な作業方法です。これは、既存のC++関数がLua APIに適切でない(または単に存在しない)特殊なインタフェースを作成するためによく使用されます。
これらの定義を含む適切なヘッダーを生成するには、-external-runtime
引数を使用します。これは、.cppファイルを生成するステップとは異なるSWIG実行ステップでなければなりません。実際、SWIGファイルなどは実際には処理されません。必要なのは、ターゲット言語(-lua
)と、C++(-c++
)を使用しているかどうかです。swig -c++ -lua -external-runtime someheader.h
のコマンドがあるだけで、タイプとマクロを取得するだけです。
はあなたがLuaのにSWIG-バインドされたオブジェクトを添付したいどんなソースでそのヘッダをインクルードします。
この偉大な答えをいただき、ありがとうございます。私は現在、生成されたSWIG cppソースファイルを掘り下げており、あなたが記述したものの正確さのレベルを十分に理解することができます。はい、それはこれを働かせるエレガントな方法を見つけるための長い道のりになると思われます。 ありがとうございます! 編集:これを行うボタンが表示されるとすぐにこれを回答としてマークします。 – damian