SWIG TypeError: in method 'my_method', argument 1 of type 'double const []'

SWIG TypeError: in method 'my_method', argument 1 of type 'double const []'

我正在尝试使用 swig 将 c 函数包装到 python 中。

在 my_method.h 中定义并在 my_method.c 中实现的函数是:

double my_method(const double a[], const double b[], const long int len_a, const long int len_b){
...
}

我的 swig 接口文件 (my_method.i) 是:

/* file : my_method.i */

/* name of the python module*/
%module my_method
%{
    #include "my_method.h"
%}

%include "my_method.h"

我使用 dist-utils 生成包装函数

#!/usr/bin/env python

"""
setup.py file for SWIG wrapping
"""

from distutils.core import setup, Extension

my_method_module = Extension('_my_method',
                           sources=['my_method.c', 'my_method_wrap.c'],
                           )

setup (name = 'my_method',
       version = '0.1',
       author      = "author",
       description = """my method""",
       ext_modules = [my_method_module],
       py_modules = ["my_method"],
       )

然后

swig -python my_method.i
python setup.py build_ext --inplace

然而当我 运行 我的主脚本在 python:

a = np.ones(4)
b =  np.ones(4)
res = my_method(a, b, len(a), len(b))

我收到以下错误:

    return _my_method.my_method(a, b, len_a, len_b)
TypeError: in method 'my_method', argument 1 of type 'double const []'

有什么建议吗?

SWIG 不知道 double a[] 表示一个或多个双打,或者 len_a 表示长度。 NumPy 有一个 SWIG 接口文件,它定义了将指针和大小与一个名为 numpy.i (docs) (download).

的 numpy 数组或 Python 列表相关联所需的类型映射。

这是一个独立的例子。您需要重新排序参数以便 pointer/size 在一起或添加适配器函数。我已经演示了后者,以防无法重新排序:

%module test

%{
#define SWIG_FILE_WITH_INIT

// sample implementation of OP function.
// Just sum all the values in both arrays.
double my_method(const double a[], const double b[], const long int len_a, const long int len_b) {
    double sum = 0.0;
    for(long int aa = 0; aa < len_a; ++aa)
        sum += a[aa];
    for(long int bb = 0; bb < len_b; ++bb)
        sum += b[bb];
    return sum;
}

// adapter function in case re-ordering parameters is not possible
double my_method2(const double a[], int len_a, const double b[], int len_b) {
    return my_method(a, b, len_a, len_b);
}
%}

%include "numpy.i"

%init %{
import_array();
%}

// apply the typemaps for numpy arrays to the two pairs of parameters representing the arrays
%apply (double* IN_ARRAY1, int DIM1) {(double* a, int len_a)};
%apply (double* IN_ARRAY1, int DIM1) {(double* b, int len_b)};

// process the adapter function and rename
%rename(my_method) my_method2;
double my_method2(double* a, int len_a, double* b, int len_b);

我在 Windows 上使用 MSVC 构建。请注意,Python 及其 NumPy 包 headers:

需要包含路径
swig -python test.i
cl /LD /W3 /Ic:\python310\include /Ic:\Python310\Lib\site-packages\numpy\core\include /Fe_test.pyd test_wrap.c -link /libpath:c:\python310\libs

演示:

>>> import test
>>> test.my_method([1, 2, 3], [4, 5, 6])
21.0
>>> import numpy as np
>>> a = np.ones(4)
>>> b = np.ones(4)
>>> test.my_method(a, b)
8.0