2

我有一个 C++ 类,其中一个方法返回一个double *类似数组的数组,它是它的成员变量之一。我试图让它作为 Python 中的列表访问。我将它包装在 adoubleArray_frompointer中,然后尝试使用 deepcopy 将其安全地从那里取出,但是当doubleArray超出范围时我仍然遇到问题,它的内存被清理,然后 C++ 类尝试清理相同的内存(尽管我创建的要点中没有显示)。

我怀疑我应该使用类型映射来执行此操作。

我要包装的是:

double *foo() {
  double *toReturn = new double[2];
  toReturn[0] = 2;
  toReturn[1] = 4;
  return toReturn;
}

界面是:

%module returnList
%include "returnList.h"

%include "cpointer.i"
%pointer_functions(double, doubleP)

%include "carrays.i"
%array_class(double, doubleArray);

%{
#include "returnList.h"
%}
4

2 回答 2

3

您说得对,可以使用类型映射来避免在 Python 端编写循环。我举了一个例子 - 它与其他答案非常相似。

%module test

%typemap(out) double *foo %{
  $result = PyList_New(2); // use however you know the size here
  for (int i = 0; i < 2; ++i) {
    PyList_SetItem($result, i, PyFloat_FromDouble($1[i]));
  }
  delete $1; // Important to avoid a leak since you called new
%}

%inline %{
double *foo() {
  double *toReturn = new double[2];
  toReturn[0] = 2;
  toReturn[1] = 4;
  return toReturn;
}
%}

这里的类型映射匹配一个称为foo返回的函数 - 你可以匹配更广泛,但是对于返回并不意味着你返回一个大小为 2 的数组的double *函数,会有做错事情的风险。double *

使用此类型图,我可以运行:

Python 2.6.6 (r266:84292, Dec 27 2010, 00:02:40)
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import test
>>> test.foo()
[2.0, 4.0]
>>>

您需要像这样手动编写它的原因是因为 SWIG 无法推断您从中返回的数组的长度foo。它甚至可以在呼叫之间有所不同。

于 2012-12-29T10:03:37.533 回答
0

I 'solved' the problem not by returning any sort of vector- or array-like object, but instead by recreating in Python the (simple) loop that generated the array in the first place. That is, my C++ code only has to return individual doubles, and my Python code will assemble the list.

To be slighly more explicit, I have the C++ method double *simulation.run(), that was causing trouble. I created a new C++ method double simulation.doRound(), and then called this via SWIG in a Python loop of numRounds iterations, doing outputs.append(simulation.doRound()) each iteration.

However, I would still like to know how to copy a C/C++ double * array to a Python list via SWIG, since this seems like such a basic operation. If someone could answer that, I'd mark such as the accepted answer.

于 2012-12-26T05:08:33.267 回答