我一直在尝试使用SWIG来包装一个简单的库,该库使用ioctl()来填充如下结构:
struct data
{
header* hdr;
void* data;
size_t len;
};
数据是指向缓冲区的指针, len 是该缓冲区的长度。
我无法弄清楚如何将数据转换为Python字符串(或数组)。此外,我需要一种方法来释放析构函数中的缓冲区。任何建议都表示赞赏。
答案 0 :(得分:1)
由于您在Q标题中说“或其他” - 如果您选择使用ctypes,则可以使用void*
代表c_void_p
(其中一个是ctypes'{{ 3}},并从C运行时库中访问free
和memcpy
等函数(只要后者可用作DLL / .so动态库,但现在这种情况非常广泛)。要获取可以memcpy
数据的可变字符缓冲区,请使用fundamental data types。
当然你也可以使用Python C API - create_string_buffer就是你在这种情况下用来从void*
和长度(当然你是')进行字节数组复制的d,在适当的时候直接调用free
,因为它只是C代码。)
另一种考虑的可能性是PyByteArray_FromStringAndSize,一种类似Python的语言,用于编写Python扩展,并且Cython编译器可以从Cython源生成可编译的C代码 - 在Cython中,您的struct
将是:
cdef struct data:
void* hdr
void* data
unsigned int* len
假设您不想麻烦地宣布header
(即,此处只有data
和len
对您很重要) - size_t
,我相信,此时不是Cython的一部分(我可能错了,他们会继续添加内容;-),但unsigned int
可能会这样做。
很抱歉,自从我认真使用SWIG以来已经太久了(所有这些优秀的替代方案) - 如果不是因为标题中那个诱人的“或别的”条款,我会跳过Q.-)
答案 1 :(得分:1)
swig提供了一个名为“cdata.i”的模块。您应该在接口定义文件中包含它。
包含此内容后,它会提供两个函数cdata()和memmove()。给定void *和二进制数据的长度,cdata()将其转换为目标语言的字符串类型。 memmove()是相反的。给定一个字符串类型,它会将字符串的内容(包括嵌入的空字节)复制到C void *类型中。
使用此模块处理二进制数据变得非常简单。我希望这就是你所需要的。