SWIGを使用して、CライブラリへのPython言語バインディングを生成しています。バインディングを構築し、データ構造をエクスポートすることができましたが、ライブラリを使用するときにいくつかのフープを飛び越える必要があります。
たとえば、Cヘッダーには次のようなデータ型と関数プロトタイプがあります。
struct MyStruct
{
/* fields */
}
struct MyStruct * MYSTRUCT_Alloc(void);
void MYSTRUCT_Free(struct MyStruct *);
struct MyStruct * MYSTRUCT_Clone(const struct MyStruct *);
int MYSTRUCT_Func1(const struct MyStruct *, const int);
/* and so on */
SWIGインターフェイスファイルで、関数とMyStructデータ型の両方をエクスポートしています。私のPython拡張モジュールがfoobarと呼ばれていると仮定すると、次のようなPythonスクリプトを記述できます。
#import foobar as fb
# The line below creates a Python class which is a wrapper to MyStruct. HOWEVER I cannot pass this class to a function like MYSTRUCT_Func1 until I have initialized it by calling MYSTRUCT_Alloc ...
ms = fb.MyStruct
# This will fail (throws a Python exception)
# ret = fb.MYSTRUCT_Func1(ms, 123)
# However this works
ms = fb.MYSTRUCT_Alloc()
ret = fb.MYSTRUCT_Func1(ms, 123)
オブジェクトを宣言し、それを使用する前にオブジェクトへのポインタを割り当てるのは非常に面倒です(そしてエラーが発生しやすくなります)。SWIGで生成されたクラスを使用するより良い方法はありますか?オブジェクトの作成と破棄を自動的に処理するために(またはMYSTRUCT_Func1()のようないくつかのOBVIOUSメンバー関数を提供するために、より高いレベルのクラスをラップする(またはSWIGで生成されたクラスをサブクラス化する)ことを考えていました。
ただし、SWIGで生成されたクラスをラップ/サブクラス化すると、C構造体へのポインターを期待するCAPI関数に新しいクラスを渡すことができるかどうかわかりません。SWIGで生成されたクラスを直接変更することはできません(または少なくとも変更すべきではありません)-明らかな理由から。
この問題を解決するための最良の方法は何ですか?オブジェクトを作成/破棄すると同時に、公開されたC関数に直接ポインターを渡すことができる、よりPython的な方法ですか?