在SWIG中为包含联合体的结构创建类型映射(Python)
我刚开始使用SWIG,正在为以下结构体创建一个Python的类型映射,但遇到了一些困难:
typedef struct si2drExprT
{
si2drExprTypeT type;
union
{
si2drInt32T i;
si2drFloat64T d;
si2drStringT s; /* most likely an identifier */
si2drBooleanT b;
} u;
si2drValueTypeT valuetype; /* if the type is a fixed value */
struct si2drExprT *left; /* the exprs form a classic binary tree rep of an arithmetic expression */
struct si2drExprT *right;
} si2drExprT;
目前这个结构体在一个函数调用中被使用:
si2drVoidT si2drIterNextComplexValue ( si2drValuesIdT iter,
si2drValueTypeT *type,
si2drInt32T *intgr,
si2drFloat64T *float64,
si2drStringT *string,
si2drBooleanT *boolval,
si2drExprT **expr,
si2drErrorT *err )
我需要si2drExprT **expr
作为输出,而不是指针。我已经成功地用%apply int *OUTPUT { si2drErrorT* err };
的格式创建了几个其他指针的输出。
我读过大部分关于SWIG的文档,特别是关于类型映射和Python类型映射的部分。我对它们的写法和工作原理有一定的理解,但对于这个结构体应该如何进行类型映射,我还是感到困惑。
我不能切换到ctypes,因为最终我还需要为Perl做同样的事情,而SWIG似乎是转换成多种语言的最佳选择(这是我所知道的)。而且我无法控制C函数的定义,我的包装转换必须独立于C库。
有没有人能给我一个示例让我知道该怎么做?我找不到我需要的那种示例。
我非常感谢任何提供的帮助。
-- 编辑 --
我在Python中的预期使用方式大概是这样的:
(some_int, some_flt, some_str, some_bool, some_expr, error) = si2drIterNextComplexValue(some_iter)
其中some_expr的值是一个元组或字典之类的东西。虽然这可能不完全可行,但我希望能有一些建议,如何将其作为输出,以便我可以在Python中提取定义的联合值。
所有传递给C函数的指针参数都被视为输出,*类型告诉用户应该查看哪个指针值。
1 个回答
使用SWIG,你可以完全改变接口的方式。比如,你可以在你的.i文件中创建一个新的类,这个类用来存储指针,并返回这个类的一个实例:
// .i file:
... what you have already to export si2dr* types ...
struct ExprWrapper {
si2drValueTypeT type;
si2drInt32T intgr;
si2drFloat64T float64,
si2drStringT string;
si2drBooleanT boolval;
si2drExprT *expr;
si2drErrorT err;
};
%inline %{
ExprWrapper si2drIterNextComplexInt(si2drValuesIdT iter) {
ExprWrapper wrapper;
si2drIterNextComplexInt(iter, & wrapper.type, ..., & wrapper.expr, & wrapper.err);
return wrapper;
)
%}
你可能需要告诉SWIG谁拥有ExprWrapper中的expr字段(是你自己还是Python -- 可以查看SWIG的文档),但这种方法应该比较简单明了。