【问题标题】:How Python can get binary data(char*) from C++ by SWIG?Python 如何通过 SWIG 从 C++ 获取二进制数据(char*)?
【发布时间】:2011-12-31 03:04:45
【问题描述】:

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

例如:

example.h:

char * fun()
{
    return "abc\0de";
}

现在在 Python 中,我们调用 例子.fun() 它只打印 “ABC” 代替 "abc\0de" '\0' 后面的数据被 Python 删除了。

我想从 C++ 中的 fun() 中获取所有字符(它是可以包含 '\0' 的二进制数据), 并感谢任何建议

【问题讨论】:

标签: c++ python char swig


【解决方案1】:

首先,如果您正在处理二进制数据(swig 认为它们是普通字符串),则不应使用char *。相反,您应该使用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)

【讨论】:

  • 能否也举个例子说明如何使用memmove()
【解决方案2】:

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 了解如何使用它。

【讨论】:

  • 对不起我的英语不好(哈哈,我是中国人),你帮我解决了困扰我大约一个星期的问题。非常感谢~~~
【解决方案3】:

请参阅文档中的8.3 C String Handling

同样来自documentation

char * 数据类型作为以 NULL 结尾的 ASCII 字符串处理。痛饮 将其映射为目标脚本中的 8 位字符串 语言。 SWIG 将目标语言中的字符串转换为 在将字符串传递到 C/C++ 之前以 NULL 终止字符串。默认 处理这些字符串不允许它们嵌入 NULL 字节。因此,char * 数据类型一般不适合 传递二进制数据。但是,可以更改此行为 通过定义 SWIG 类型映射。有关详细信息,请参阅 Typemaps 章节 关于这个。

【讨论】:

    猜你喜欢
    • 2021-04-17
    • 1970-01-01
    • 2020-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-21
    • 2013-01-19
    相关资源
    最近更新 更多