SWIG C/python 和无符号字符指针
Posted
技术标签:
【中文标题】SWIG C/python 和无符号字符指针【英文标题】:SWIG C/python and unsigned char pointers 【发布时间】:2017-09-04 01:26:07 【问题描述】:我在表单中有一个函数
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 的方法(编码、字节数组、[0]*100 等)但似乎没有任何效果......
这应该如何工作?
以防万一,这可能会产生一些影响,这是一个 C 函数,所以为了避免损坏,我用
包装它extern "C"
...
很遗憾,我无法更改 c 代码
【问题讨论】:
尝试使用ctypes
,分配一个数组并通过引用传递。
C != C++。请确保使用您使用的实际语言进行标记(大概是 C)。
它是嵌入在 C++ 11 应用程序中的遗留代码。编译器是 C++(修改等),这就是我澄清 extern "C" 的原因,因为它确实改变了函数的签名。
【参考方案1】:
您的 python 字符串似乎与 C 函数的预期参数类型不兼容。 this 可能会对您有所帮助。它建议使用 c_char_p 来获得正确的类型。也就是说,如果您想在不复制字符串的情况下这样做,但有一些限制。
如果您可以根据需要定义或复制字符串,则有 ctypes,其中一个是 c_ubyte
。
【讨论】:
【参考方案2】:感谢您的回答。
我知道如何使用 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 的正确性,我在这个答案中避免这样做以保持简单。但应该考虑到这一点。
【讨论】:
【参考方案3】:尝试改用unsigned char data[]
。
如果您使用的是 C++,请尝试通过 STL 中的 String 类传入。
【讨论】:
以上是关于SWIG C/python 和无符号字符指针的主要内容,如果未能解决你的问题,请参考以下文章