Python SWIG : convert C++ return parameter to return value, 并将原始 C++ 类型转换为 Python 类型

标签 python c++ swig

我正在尝试修改 C++ 库的现有 SWIG Python 接口(interface),以添加 Python 包装器以实现更多功能,并且非常感谢有 SWIG 经验的人提供帮助。

具体来说,我正在开发一个具有如下签名的函数:

void execute(int x, double y, ResultType& result1, ResultType& result2);

该函数接受两个空的 ResultType 对象并将它们填充为输出参数。在 Python 中,这必须转换为仅接受 xy 的函数,然后返回 result1result2< 的元组.

ResultType 是在整个库中广泛使用的容器类型。

类型映射(输入)

通过研究,我想我明白我需要为 result1 和 result2 添加一个“in”类型映射,它会吞下参数并将它们保存到临时变量中。我还发现 SWIG 将引用转换为指针,因此使用 &temp 而不是 temp。这是我的类型映射“in”:

typemap(in, numinputs=0) ResultType& result1 (ResultType temp) {
    $1 = &temp;
}

typemap(in, numinputs=0) ResultType& result2 (ResultType temp) {
    $1 = &temp;
}

类型映射(argout)

接下来,我添加了一个类型映射“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 对象转换为属于 SWIG 生成的 ResultType 包装器的 PyObject * ? (抱歉,如果细节太多,我正在努力避免“XY 问题”)

最佳答案

就像 $1 是对输入类型映射中的 Python 输入对象的引用一样,$1 是对 argout 类型映射中的 C++ 输出变量的引用。使用它,您可以为该数据生成一个 Python 对象并将其附加到结果中。

以下是 Windows 的功能示例:

测试.h

#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);

测试.cpp

#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;
}

测试.i

%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

关于Python SWIG : convert C++ return parameter to return value, 并将原始 C++ 类型转换为 Python 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49121312/

相关文章:

python - numpy数组将多列除以一列

python - 如何更改python代码中pd.DateOffset中的参数?

python - 找到视频点和现实世界点之间的映射

python - 在 numba 中创建一个空列表列表

Perl:构造一个对象数组

java - 更改 shared_ptr 的 getCPtr() 可见性

c++ - 创建临时文件的多种方法 : what is the situation behind each method?

c++ - fatal error : iostream: No such file or directory 3

c++ - 我如何从ptree异常中获取xml行号

c++ - 使用 swig 使 C++ 类看起来像一个 numpy 数组