我正在使用 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 生成的类?我正在考虑包装更高级别的类(或子类化 SWIG 生成的类)以自动处理对象的创建和销毁(以及提供一些 OBVIOUS 成员函数,如 MYSTRUCT_Func1()。
但是,如果我对 SWIG 生成的类进行包装/子类化,那么我不确定是否可以将新类传递给期望指向 C 结构的指针的 C API 函数。我不能直接修改 SWIG 生成的类(或者至少我不应该)——出于显而易见的原因。
解决此问题的最佳方法是什么?创建/销毁对象的更 Pythonic 方式,同时能够将指针直接传递给暴露的 C 函数?