我有一个C ++类,其中一个方法返回一个double *
数组,它是其成员变量之一。我试图将其作为Python中的列表进行访问。我将它包装在doubleArray_frompointer
中,然后尝试使用deepcopy安全地将其从那里取出,但是当doubleArray
超出范围,清除内存,然后清除时,我仍然会遇到问题C ++类试图清理相同的内存(虽然我创建的gist中没有显示)。
我怀疑我应该使用打字机做这件事。
我想要包装的是:
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"
%}
答案 0 :(得分:3)
你说可以使用类型映射来避免在Python端编写循环是正确的。我把一个例子放在一起 - 它与this other answer非常相似。
%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;
}
%}
这里的typemap与一个名为foo
的函数匹配,返回double *
- 你可以更广泛地匹配,但是对于返回double *
没有'的函数来说,存在冒错误的风险这意味着你要返回一个大小为2的数组。
使用此类型地图,我可以运行:
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
返回的数组的长度。它甚至可能因电话而异。
答案 1 :(得分:0)
我'解决'问题不是通过返回任何类型的矢量或类似数组的对象,而是通过在Python中重新创建首先生成数组的(简单)循环。也就是说,我的C ++代码只需返回单个双精度数,而我的Python代码将汇总列表。
为了更加明确,我有C ++方法double *simulation.run()
,这导致了麻烦。我创建了一个新的C ++方法double simulation.doRound()
,然后在numRounds
次迭代的Python循环中通过SWIG调用它,每次迭代都进行outputs.append(simulation.doRound())
。
但是,我仍然想知道如何通过SWIG将C / C ++ double *
数组复制到Python列表,因为这看起来像是一个基本的操作。如果有人可以回答这个问题,我会标记为接受的答案。