python - swig,传递没有指定尺寸的 carrays

标签 python c++ swig

这是我要包装的部分代码:

typedef unsigned char UINT8;
...
void fn(UINT8 data[]);

在 .i 文件中,我包括:

From 8.2.2 carrays.i:
%array_class(UINT8, UINT8Array)

支持数组写操作:

%typemap(in) UINT8[ANY] ($1_basetype temp[$1_dim0]) {
    int i;
    if (!PySequence_Check($input)) {
        PyErr_SetString(PyExc_ValueError,"Expected a sequence as input");
        return NULL;
    }
    if (PySequence_Length($input) != $1_dim0) {
        PyErr_SetString(PyExc_ValueError,"Input sequence size incorrect, should have $1_dim0 ints");
        return NULL;
    }
    for (i = 0; i < $1_dim0; i++) {
        PyObject *o = PySequence_GetItem($input,i);
        if (PyNumber_Check(o)) {
            temp[i] = ($1_basetype)PyInt_AsLong(o);
            Py_DECREF(o);
        } else {
            Py_XDECREF(o);
            PyErr_SetString(PyExc_ValueError,"Input sequence elements must be numbers");      
            return NULL;
        }
    }
    $1 = temp;
}

然后,在编译时,我的代码失败了:

example_wrap.cxx:40:15: error: storage size of ‘temp2’ isn’t known
   UINT8 temp2[] ;

请注意,如果我的函数是这样的,则包装有效:

void fn(UINT8 数据[10]);

void fn(UINT8* 数据);

有什么方法可以告诉我 swig,当有一个 UINT8[] 来表征它时,因为它是一个 UINT8 *。像这样:

%typemap(in) UINT8[] ($1_basetype *temp) {

谢谢, 巴勃罗

最佳答案

在评论中,OP 声明函数参数具有固定大小。假设头文件如下所示:

#ifdef _WIN32
#   define API __declspec(dllexport)
#else
#   define API
#endif

typedef unsigned char UINT8;

API void fn(UINT8 data[]); // data must be length 300

OP 的类型图有效,但不知道大小。要让 SWIG 知道有一个固定大小并仍然利用通用类型映射,可以使用以下内容:

%module test

%{
#include "test.h"

// Implementation...this would normally be in a .cpp file and linked in.
// Note to see the result an argout typemap would be needed too...
API void fn(UINT8 data[]) {
    for(int i = 0; i < 300; ++i)
        data[i] += 1;
}
%}

// OP's original generalized array typemap...
%typemap(in) UINT8[ANY] ($1_basetype temp[$1_dim0]) {
    int i;
    if (!PySequence_Check($input)) {
        PyErr_SetString(PyExc_ValueError,"Expected a sequence as input");
        return NULL;
    }
    if (PySequence_Length($input) != $1_dim0) {
        PyErr_SetString(PyExc_ValueError,"Input sequence size incorrect, should have $1_dim0 ints");
        return NULL;
    }
    for (i = 0; i < $1_dim0; i++) {
        PyObject *o = PySequence_GetItem($input,i);
        if (PyNumber_Check(o)) {
            temp[i] = ($1_basetype)PyInt_AsLong(o);
            Py_DECREF(o);
        } else {
            Py_XDECREF(o);
            PyErr_SetString(PyExc_ValueError,"Input sequence elements must be numbers");
            return NULL;
        }
    }
    $1 = temp;
}

// Assume there are lots of other functions in test.h,
// but we don't want to wrap the function that requires
// a fixed-sized array and doesn't declare the size.
%ignore fn;

// Process test.h, but skip wrapping fn.
%include "test.h"

// This "un-ignores" the function and provides a replacement
// that declares the fixed size.
// See http://www.swig.org/Doc3.0/SWIGDocumentation.html#SWIG_rename_ignore
%rename("%s") fn;
void fn(UINT8 temp[300]);

演示:

>>> import test
>>> test.fn([1,2,3])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Input sequence size incorrect, should have 300 ints
>>> test.fn([1]*300)  # This works
>>> test.fn('a'*300)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Input sequence elements must be numbers

关于python - swig,传递没有指定尺寸的 carrays,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56510482/

相关文章:

c++ - Swig:如何包装 double&(double 通过引用传递)?

python - 如何使用 bottlenose 创建远程亚马逊购物车

Python - 类型错误 : object of type '...' has no len()

C++ 强制模板参数

java - 如何使用SWIG包装std::function对象?

python - SWIG 在结构内分配数组的内存问题

python - 有没有 `ufunc`只是转发数据?

python - 在Python中使用execute()/executemany()执行SQL语句

c++ - 取消 pthread_cond_wait() 挂起与 PRIO_INHERIT 互斥锁

c++ - 压缩字符串存储