【问题标题】:What is the best way to return a string to the SWIG python interface?将字符串返回到 SWIG python 接口的最佳方法是什么?
【发布时间】:2014-07-07 14:52:02
【问题描述】:

将字符串从 C++ 返回到 SWIG python 接口的线程安全且无内存泄漏的方法是什么?

SWIG 会自动将 char * 返回值的内容复制到 python 字符串中。 This SWIG guide 举个例子:

char *__str__() {
    static char temp[256];
    /* WRITE STUFF TO STRING */
    return &temp[0];
}

他们的示例使用静态字符串作为返回值,但如果我的 C++ 程序有多个线程,它们很容易覆盖彼此的字符串。

返回新分配的字符串会造成内存泄漏,因为 SWIG 不知道释放它。

我唯一能想到的就是注册并返回一个指向实际 python 字符串对象的指针(这样 python 垃圾收集器就会处理它),但我不知道该怎么做,我想知道如果有更简单的方法。

【问题讨论】:

  • 让调用者提供缓冲区并且 C++ 代码只是复制到该缓冲区的经过验证的真实方法怎么样?例如,Windows API 就是这样处理字符串的。
  • @PaulMcKenzie 我认为这不适用于 SWIG。首先,SWIG 只能提供一个指向不可变 python 字符串的原始数据的指针,如果修改它会使 python 崩溃。其次,这会违反 __str__ 等方法的接口,这些方法不应该有任何参数传递给它们。
  • 您是否尝试过创建一个返回 std::string 的包装器?
  • @Matt - I don't think that would work with SWIG. First of all, SWIG would only be able to supply a pointer to the raw data of an immutable python string 如果无法将可修改的缓冲区传递给函数,那么 SWIG 将严重缺乏功能。 Second of all, that would violate the interface of methods such as __str__, which are not supposed to have any arguments passed to them那也许你应该写一个C++工厂类来分配和返回字符串。
  • @Matt 你的意思是“......但是 SWIG 转换”,对吗?已经有一段时间了,但我很确定确实如此,但您需要包含 std::string 类型映射。

标签: python c++ string memory-management swig


【解决方案1】:

SWIG 创建包装器代码以在 C++ std::string 和 Python 字符串之间进行转换,如果您包含在 std_string.i 中定义的类型映射。

【讨论】:

  • 谢谢!我做了%include <std_string.i>,它成功了!
  • 如果 std::string 是在 C++ 方法中创建的,它是否处理释放它?还是需要在C++方法上指定%new_object?
  • @jason 需要 newobj 但不确定,对使用和不使用 newobj decl 的生成代码进行并排比较,应该只显示几行不同。
  • 所以我的评论的答案是,如果std::string 是用new 创建的,那么它必须被手动删除,swig 会用%newobject 做到这一点。但是如果std::string 是使用std::string myStr 之类的声明创建的,那么C++ 会处理它的生命周期,%newobject 不会影响生成的代码。
猜你喜欢
  • 1970-01-01
  • 2014-03-19
  • 2021-10-29
  • 1970-01-01
  • 2018-08-23
  • 2011-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多