Python如何通过SWIG从C ++中获取二进制数据(char *)?

How Python can get binary data(char*) from C++ by SWIG?

我在Syg中使用Python中的C++函数,现在我遇到了一个问题。当我将Car从C++传递到Python时,chy*被Python截断。

例如:

示例.h:

1
2
3
4
char * fun()
{
    return"abc\0de";
}

现在在python,我们称之为示例.fun()它只打印"ABC"而不是"ABCde"python删除了''后面的数据。

我想得到所有的字符(它是一个二进制数据,可以包含"0")从CF()中的C+,谢谢你的建议


首先,如果处理的是二进制数据(swig认为它们是正常字符串),则不应使用char *。相反,您应该使用void *。swig提供了一个名为"cdata.i"的模块-您应该将它包含在接口定义文件中。

一旦包含了这个函数,它将提供两个函数——cdata()memmove()

  • 给定void *和二进制数据的长度,cdata()将其转换为目标语言的字符串类型。
  • memmove()执行相反的操作—给定一个字符串类型,它将把字符串的内容(包括嵌入的空字节)复制到c void*类型中。

使用这个模块,处理二进制数据变得简单多了。我希望这是你需要的。

1
2
3
4
5
6
7
8
9
10
11
12
13
example.i
%module example
%include"cdata.i"
%{
void *fun()
{
        return"abc\0de";
}
%}

test.py
import example
print example.cdata(example.fun(), 6)


C/C++字符串是null结尾的,这意味着第一个EDCOX1×0字符表示字符串的结尾。

当一个函数返回一个指向这样一个字符串的指针时,调用者(在本例中是swig)无法知道第一个\0之后是否有更多的数据,因此您只能得到第一个部分。

所以,首先要做的是更改C函数,返回的不仅仅是字符串,还有字符串的长度。因为只能有一个返回值,所以我们将改用指针参数。

1
2
3
4
5
void fun(char** s, int *sz)
{
    *s ="abc\0de";
    *sz = 6;
}

swig文档建议使用cstring.i库包装这些函数。在particullar中,最后一个宏完全按照您的需要执行。

1
%cstring_output_allocate_size(parm, szparm, release)

阅读文档以了解如何使用它。


参见文档中的8.3 C字符串处理。

同样来自文件:

The char * datatype is handled as a NULL-terminated ASCII string. SWIG
maps this into a 8-bit character string in the target scripting
language. SWIG converts character strings in the target language to
NULL terminated strings before passing them into C/C++. The default
handling of these strings does not allow them to have embedded NULL
bytes. Therefore, the char * datatype is not generally suitable for
passing binary data. However, it is possible to change this behavior
by defining a SWIG typemap. See the chapter on Typemaps for details
about this.