我正在尝试为C ++库修改现有的SWIG Python接口,以添加Python包装器以实现更多功能,并且非常感谢SWIG经验丰富的人员提供的帮助。
具体来说,我正在使用具有以下特征的函数:
void execute(int x, double y, ResultType& result1, ResultType& result2);
此函数接受两个空的ResultType对象,并将其填充为输出参数。在Python中,这必须转换为仅包含xand的函数y,然后返回result1and的元组result2。
x
y
result1
result2
ResultType是在整个库中广泛使用的容器类型。
从研究中,我认为我了解我需要为result1和result2添加一个“在”中的类型映射,该映射将吞入参数并将其保存为临时变量。我还发现该引用是由SWIG&temp而不是转换为指针的temp。这是我的“类型”输入:
&temp
temp
typemap(in, numinputs=0) ResultType& result1 (ResultType temp) { $1 = &temp; } typemap(in, numinputs=0) ResultType& result2 (ResultType temp) { $1 = &temp; }
接下来,我添加了一个类型映射“ argout”,将值附加到返回元组:
%typemap(argout) ResultType& result1 { $result = SWIG_Python_AppendOutput($result, temp$argnum); } %typemap(argout) ResultType& result2 { $result = SWIG_Python_AppendOutput($result, temp$argnum); }
但是,这显然是行不通的,因为temp$argnum它将是原始C 类型的ResultType,而我需要有一个PyObject *才能附加到元组。ResultType已经具有可用的SWIG包装器。因此,在Python中,我可以调用ResultType()构造它的实例而不会出现问题。假设到目前为止我处在正确的轨道上,如何将原始C ResultType对象转换PyObject *为SWIG生成的包装器的所属ResultType?(很抱歉,如果细节过多,我正试图避免出现“ XY问题”)
temp$argnum
ResultType
PyObject *
ResultType()
就像$ 1是对输入类型图中的Python输入对象的引用一样,$ 1是对argout类型图中的C ++输出变量的引用。使用此方法,您可以为该数据生成一个Python对象,并将其附加到结果中。
这是Windows的功能示例:
测试
#ifdef EXPORT #define API __declspec(dllexport) #else #define API __declspec(dllimport) #endif struct ResultType { int x; double y; }; API void execute(int x, double y, ResultType& result1, ResultType& result2);
测试文件
#define EXPORT #include "test.h" API void execute(int x, double y, ResultType& result1, ResultType& result2) { result1.x = 2 * x; result1.y = 2 * y; result2.x = 3 * x; result2.y = 3 * y; }
%module test %{ #include "test.h" %} %include <windows.i> %typemap(in,numinputs=0) ResultType& %{ // Create a persistent object to hold the result; $1 = new ResultType; %} %typemap(argout) ResultType& (PyObject* tmp) %{ // Store the persistent object in a PyObject* that will be destroyed // when it goes out of scope. tmp = SWIG_NewPointerObj($1, $1_descriptor, SWIG_POINTER_OWN); $result = SWIG_Python_AppendOutput($result, tmp); %} %include "test.h"
输出量
>>> import test >>> r = test.execute(2,3) >>> r[0].x 4 >>> r[0].y 6.0 >>> r[1].x 6 >>> r[1].y 9.0