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

kai*_*521 4 c++ python swig char

我正在使用SWIG的Python中的C++函数,现在我遇到了一个问题.当我将char*从C++传递给Python时,char*被Python中断.

例如:

example.h文件:

char * fun()
{
    return "abc\0de";
}
Run Code Online (Sandbox Code Playgroud)

现在在Python中,我们称之为example.fun()只打印的,而不是"ABC\0de"背后的"\ 0"的数据是由Python的删除"ABC".

我想从C++中的fun()得到所有字符(它是一个可以包含'\ 0'的二进制数据),任何建议都表示赞赏

sun*_*nil 8

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

一旦你包括它,它提供了两个功能 - cdata()memmove().

  • 给定a 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)
Run Code Online (Sandbox Code Playgroud)

  • 您还可以举例说明如何使用`memmove()`吗? (2认同)

yak*_*yak 6

C/C++字符串以NULL结尾,这意味着第一个\0字符表示字符串的结尾.

当一个函数返回一个指向这样一个字符串的指针时,调用者(在本例中为SWIG)无法知道第一个之后是否有更多的数据,\0这就是为什么你只得到第一个部分.

所以要做的第一件事就是改变你的C函数,不仅返回字符串,还返回它的长度.由于只能有一个返回值,我们将使用指针参数.

void fun(char** s, int *sz)
{
    *s = "abc\0de";
    *sz = 6;
}
Run Code Online (Sandbox Code Playgroud)

SWIG文档建议使用cstring.i 来包装这些函数.特别是,最后一个宏完全符合您的需求.

%cstring_output_allocate_size(parm, szparm, release)
Run Code Online (Sandbox Code Playgroud)

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