我的目标是使用SW和C和Python来创建一个函数,该函数将NumPy数组作为输入并返回不同的NumPy数组。返回的数组具有一些取决于输入数组的未指定大小。不幸的是,当我尝试运行我的代码时,我得到了一个返回的空数组。这是一个显示问题的“最小”示例。我通过以下方式运行此代码:
python setup.py build_ext --inplace
python test.py
感兴趣的文件复制如下。如果您知道如何使此代码返回非空的NumPy数组,请告诉我。谢谢!
cancelterms.c:
#include "cancelterms.h"
void cancel(double complex* vec, int m, int n, double complex sum[])
{
// Some code that processes vec.
// This is just an example. In practice the following lines will depend on vec.
sum[0] = 1.0;
sum[1] = 2.5;
sum[2] = 3.6;
}
cancelterms.h:
#include <stdlib.h>
#include <stdio.h>
#include <complex.h>
void cancel(double complex* vec, int m, int n, double complex sum[]);
cancelterms.i:
%module cancelterms
%{
/* Put header files here or function declarations like below */
#define SWIG_FILE_WITH_INIT
#include "cancelterms.h"
%}
%include "numpy.i"
%include <complex.i>
%numpy_typemaps(double complex, NPY_CDOUBLE, int)
%init %{
import_array();
%}
%apply (double complex* INPLACE_ARRAY2, int DIM1, int DIM2) {(double complex* vec, int m, int n)}
%apply (double complex ARGOUT_ARRAY1[ANY]) {(double complex sum[])}
%include "cancelterms.h"
setup.py:
# Import necessary modules.
from distutils.core import setup, Extension
import numpy as np
try:
numpy_include = np.get_include()
except AttributeError:
numpy_include = np.get_numpy_include()
example_module = Extension('_cancelterms', sources=['cancelterms.c', 'cancelterms.i'], include_dirs = [numpy_include])
setup(name='cancelterms', ext_modules=[example_module], py_modules=["cancelterms"])
test.py:
import cancelterms
import numpy as np
a=np.array([[1.0j,2.0j,3.0j,4.0j,5.0j,6.0j],[-1.0j,-2.0j,-3.0j,6.0j,7.0j,8.0j]])
print cancelterms.cancel(a)
不幸的是numpy.i太大了,无法在这里粘贴,但是我使用numpy github存储库中的标准numpy.i文件,其中包含一些小修改,我将双复合添加到类型列表中。
答案 0 :(得分:0)
display:block
类型地图适用于硬编码维度的数组。这在输出数组的numpy.i docs中清楚地说明,但也适用于其他数组。
例如,它们可以用作:
...[ANY]
如果你的函数采用了一个大小为5的数组(由调用者/在包装器代码中分配)。
关键是SWIG无法知道argout数组%apply (double complex ARGOUT_ARRAY1[ANY]) {(double complex sum[5])}
的大小。你的代码编译和运行完全是巧合。看看生成的包装器代码(搜索'wrap_cancel'),你会看到发生了什么。
还有以下类型图:
sum
( DATA_TYPE* ARGOUT_ARRAY1, int DIM1 )
在你的情况下,函数( DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1 )
为数组cancel
分配内存,假设调用者有某种方法来计算大小。这种情况没有预定义的类型图。
这类似于函数只返回sum
的情况,并且如numpy.i文档中所述:
如果遇到函数或方法返回指向数组的指针的情况,最好的办法是编写自己要包装的函数版本,对于类方法的情况使用%extend或%对于函数的情况,忽略和%重命名。