Python 未指定尺寸的swig、pass结转

Python 未指定尺寸的swig、pass结转,python,c++,swig,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($

这是我想包装的代码的一部分:

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;
}
请注意,如果我的函数类似于:

void fn(UINT8数据[10])

无效fn(UINT8*数据)

当有一个UINT8[]将其描述为UINT8*时,我有没有办法告诉swig。大概是这样的:

%typemap(in) UINT8[] ($1_basetype *temp) {
#ifdef _WIN32
#   define API __declspec(dllexport)
#else
#   define API
#endif

typedef unsigned char UINT8;

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

在评论中,OP指出函数参数的大小是固定的。假设头文件如下所示:

%typemap(in) UINT8[] ($1_basetype *temp) {
#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]);
%模块测试
%{
#包括“test.h”
//实现…这通常位于.cpp文件中并链接到。
//注意:要查看结果,还需要一个argout类型映射。。。
API无效fn(UINT8数据[]){
对于(int i=0;i<300;++i)
数据[i]+=1;
}
%}
//OP的原始广义数组类型映射。。。
%类型映射(in)UINT8[任何]($1_基类型临时[$1_dim0]){
int i;
如果(!PySequence_Check($input)){
PyErr_SetString(PyExc_ValueError,“预期序列作为输入”);
返回NULL;
}
如果(PySequence_Length($input)!=1_dim0){
PyErr_SetString(PyExc_ValueError,“输入序列大小不正确,应具有$1_dim0整数”);
返回NULL;
}
对于(i=0;i<$1_dim0;i++){
PyObject*o=PySequence\u GetItem($input,i);
如果(PyNumber_检查(o)){
温度[i]=(1美元基本类型)长度(o);
Py_DECREF(o);
}否则{
Py_XDECREF(o);
PyErr_SetString(PyExc_ValueError,“输入序列元素必须是数字”);
返回NULL;
}
}
$1=临时工;
}
//假设test.h中还有很多其他函数,
//但我们不想包装需要的函数
//固定大小的数组,不声明大小。
%忽略fn;
//过程测试.h,但跳过包装fn。
%包括“test.h”
//此“取消忽略”功能并提供替换
//它声明了固定的大小。
//看http://www.swig.org/Doc3.0/SWIGDocumentation.html#SWIG_rename_ignore
%重命名(“%s”)fn;
无效fn(UINT8温度[300]);
演示:

导入测试 >>>测试fn([1,2,3]) 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 ValueError:输入序列大小不正确,应该有300个整数 >>>test.fn([1]*300)#这是有效的 >>>测试fn('a'*300) 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 ValueError:输入序列元素必须是数字
如果不传递大小,C代码如何知道数组的长度?我知道你的意思,但此函数接收指针并以固定(恒定)的迭代次数进行迭代。类似于:fn(uint8 data[]){for(无符号n=0;n