我是使用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 };
格式成功地创建了其他几个指针输出。
我已经阅读了大多数关于类型地图和Python类型地图的SWIG文档。我非常自信我理解它们是如何编写的以及它们如何工作的概念,但是这个结构应该如何进行类型映射的复杂性让我感到难过。
我无法切换到ctypes,因为最终我需要为Perl做同样的事情,SWIG似乎是转换为多种语言的最佳选择(我知道)。我也无法控制如何定义C函数。我的包装器转换必须独立于C库。
有人能为我提供一个如何做的例子吗?我无法在任何地方找到我需要的示例级别。
我真的很感激所提供的任何帮助。
- 编辑 -
我在Python中的用途是看起来像这样:
(some_int, some_flt, some_str, some_bool, some_expr, error) = si2drIterNextComplexValue(some_iter)
some_expr值是元组或字典或其他内容。这可能是不可能的,但我愿意接受如何使它成为某种格式的输出的建议,然后我可以在Python中使用它来提取定义的union值。
C函数的所有指针参数都用作输出,其中*类型告诉用户要查看哪个指针值。
答案 0 :(得分:0)
使用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文档),但这种方法应该相当简单。