SWIG C/python 和无符号字符指针

SWIG C/python and unsigned char pointers

我在表单中有一个函数

void f(unsigned char *out, const unsigned long long outlen,
       const unsigned char *in, const unsigned long long inlen);

当我尝试使用它时:

data_in = ['a', 'b', 'c', 'd', 'e']
data_out = [0]*100
f(data_out, len(data_out), data_in, len(data_in))

(其实我想传bytearrays)

我得到类似的东西:

Traceback (most recent call last):
  File "xxxx/basic_test.py", line 6, in <module>
    f(data_out, len(data_out), data_in, len(data_in))
TypeError: in method 'f', argument 1 of type 'unsigned char *'

我尝试了不同的传递方式data_out(编码、byterray、[0]*100 等)但似乎没有任何效果...

这应该如何工作?

以防万一,这可能会产生一些影响,这是一个 C 函数,所以为了避免损坏,我用

包装了它
extern "C"
{
...
}

很遗憾,我无法更改 C 代码

请尝试使用 unsigned char data[]

如果您使用的是 C++,请尝试在 STL 中通过字符串 class 传入。

您的 python 字符串似乎与 C 函数的预期参数类型不兼容。 this 可能会对您有所帮助。它建议使用 c_char_p 来获得正确的类型。也就是说,如果您想在不复制字符串的情况下执行此操作,但有一些限制。

如果你可以随意定义字符串,或者复制它,有ctypes,其中一个是c_ubyte

感谢您的回答。

我知道如何使用 ctypes,但我的问题是关于 SWIG 的,因为我也计划为其他语言生成包装器。

存在无法修改的遗留代码(类 C),但它是更大的 C++11 库的一部分。这意味着我可能会发现重整问题等。我不想修改我公开的函数的签名。它们是 unsigned char* 的原因是因为这是原始数据。不是典型的以零结尾的 char* 字符串。 (您可以通过查看 unsigned 得到提示)

我寻求的干净解决方案是,给定一个函数

bool foo(unsigned char* data)
{
   ...
} 

编写 C++ 包装器(在某些情况下我使用了基于模板的技巧)

bool bar(vector<unsigned char> &x)
{
   foo(x.data())
}

在我做的接口文件中

%include "std_vector.i"
namespace std {
  %template(ucharVector) vector<unsigned char>;
}
... include library, etc...

和Python:

data = lib.ucharVector([1, 2, 3, 4])
answer = lib.bar(data)

注意:关于 const 的正确性,我在这个答案中避免了这一点以保持简单。但是应该考虑到。