我正在使用SWIG的Python中的C ++函数,现在我遇到了一个问题。 当我将char *从C ++传递给Python时,char *被Python中断。
例如:
example.h文件:
char * fun()
{
return "abc\0de";
}
现在用Python,我们打电话 example.fun() 它只打印 “ABC” 代替 “ABC \ 0de” “0”后面的数据被Python删除。
我想从C ++中的fun()获取所有字符(它是一个可以包含'\ 0'的二进制数据), 任何建议表示赞赏
答案 0 :(得分:8)
首先,如果您正在处理二进制数据,则不应使用char *
(swig认为它们是普通字符串)。相反,您应该使用void *
。 swig提供了一个名为'cdata.i'的模块 -
你应该在接口定义文件中包含它。
包含此功能后,它会提供两个功能 - cdata()
和memmove()
。
void *
和二进制数据的长度,cdata()
将其转换为目标语言的字符串类型。memmove()
反过来 - 给定一个字符串类型,它会将字符串的内容(包括嵌入的空字节)复制到C void*
类型中。使用此模块处理二进制数据变得更加简单。我希望这就是你所需要的。
example.i
%module example
%include "cdata.i"
%{
void *fun()
{
return "abc\0de";
}
%}
test.py
import example
print example.cdata(example.fun(), 6)
答案 1 :(得分:6)
C / C ++字符串以NULL结尾,这意味着第一个\0
字符表示字符串的结尾。
当一个函数返回一个指向这样一个字符串的指针时,调用者(在本例中为SWIG)无法知道在第一个\0
之后是否有更多数据,这就是为什么你只得到第一部分。
首先要做的是改变你的C函数,不仅要返回字符串,还要返回它的长度。由于只能有一个返回值,我们将使用指针参数。
void fun(char** s, int *sz)
{
*s = "abc\0de";
*sz = 6;
}
SWIG文档建议使用cstring.i
library来包装这些函数。特别是,最后一个宏完全符合您的需要。
%cstring_output_allocate_size(parm, szparm, release)
阅读the docs以了解如何使用它。
答案 2 :(得分:0)
请参阅文档中的8.3 C String Handling。
同样来自documentation:
char *数据类型作为以NULL结尾的ASCII字符串处理。痛饮 将其映射为目标脚本中的8位字符串 语言。 SWIG将目标语言中的字符串转换为 在将字符串传递给C / C ++之前,NULL终止了字符串。默认 处理这些字符串不允许它们嵌入NULL 字节。因此,char *数据类型通常不适合 传递二进制数据。但是,可以更改此行为 通过定义SWIG类型映射。有关详细信息,请参阅类型图章一章 关于这个。