SWIG:numpy包装器出乎意料的结果?

时间:2017-06-19 11:17:18

标签: python c++ numpy swig

不确定这是我的错误还是误解。任何帮助非常感谢。一个展示该问题的简明项目是here

我正在包装一些C ++函数,它们指向一个缓冲区(8位有符号或无符号)和一个带缓冲区长度的int,通常遵循以下模式:some_function(char * buffer,int length)

采用示例here基于以下内容生成一个看起来很健全的包装器:

example.i:

%module example

%{
    #define SWIG_FILE_WITH_INIT
    #include "example.h"
%}

// https://raw.githubusercontent.com/numpy/numpy/master/tools/swig/numpy.i
%include "numpy.i"

%init %{
    import_array();
%}

//
%apply (char* INPLACE_ARRAY1, int DIM1) {(char* seq, int n)}
%apply (unsigned char* INPLACE_ARRAY1, int DIM1) {(unsigned char* seq, int n)}
%apply (int* INPLACE_ARRAY1, int DIM1) {(int* seq, int n)}

// Include the header file with above prototypes
%include "example.h"

example.h文件:

// stubbed
double average_i(int* buffer,int bytes)
{
    return 0.0;
}

然而,运行此测试:

np_i = np.array([0, 2, 4, 6], dtype=np.int)
try:
    avg = example.average_i(np_i)
except Exception:
    traceback.print_exc(file=sys.stdout)
try:
    avg = example.average_i(np_i.data,np_i.size)
except Exception:
    traceback.print_exc(file=sys.stdout)

产生错误:

Traceback (most recent call last):
  File "test.py", line 13, in <module>
    avg = example.average_i(np_i)
TypeError: average_i expected 2 arguments, got 1
Traceback (most recent call last):
  File "test.py", line 17, in <module>
    avg = example.average_i(np_i.data,np_i.size)
TypeError: in method 'average_i', argument 1 of type 'int *'

第一个有意义,但与食谱中的例子背道而驰。第二个虽然没有,average_i 的签名是 double average_i(int* buffer,int bytes)

我哪里错了? TAIA。

[ UPDATE1

%应用根据Flexo的建议更改的定义

// integer
%apply (int* INPLACE_ARRAY1,int DIM1) {(int* buffer,int bytes)}
// signed 8
%apply (char* INPLACE_ARRAY1,int DIM1) {(char* buffer,int bytes)}
// unsigned 8
%apply (unsigned char* INPLACE_ARRAY1,int DIM1) {(unsigned char* buffer,int bytes)}

函数average_iaverage_u8现在可以按预期工作。

double average_s8(char* buffer,int bytes)仍然失败

Traceback (most recent call last):
  File "test.py", line 25, in <module>
    avg = example.average_s8(np_i8)
TypeError: average_s8 expected 2 arguments, got 1

1 个答案:

答案 0 :(得分:0)

您的%apply指令错误,与您正在包装的功能不匹配:

%apply (int* INPLACE_ARRAY1, int DIM1) {(int* seq, int n)}

这不会与您的函数average_i匹配,因为您提供的参数名称不同。更改您的%apply to match SWIG所见的声明,即:

%apply (int* INPLACE_ARRAY1, int DIM1) {(int* buffer,int bytes)}