c++ - 包装和使用返回带有 SWIG 结构的函数的问题(python)

标签 c++ python pointers struct swig

这应该是一个简单的过程,但现在我仍然想了几天。

我的情况如下:

我用 SWIG 包装了一个相对简单的 C++ 接口(interface),因此我可以将它与 Python 结合使用。然而,事情很复杂,因为其中一个方法返回一个自定义结构,其定义如下:

struct DashNetMsg {
  uint64_t timestamp;
    char type[64];
    char message[1024];
};

这是我用于完成此操作的 SWIG 接口(interface)文件:

%module DashboardClient
%{
#include "aos/atom_code/dashboard/DashNetMsg.h"
#include "DashboardClient.h"
%}

%import "aos/atom_code/dashboard/DashNetMsg.h"
%include "DashboardClient.h"

%ignore Recv(DashNetMsg *);

“DashboardClient.h”和“DashboardClient.cpp”声明并定义了类“DashboardClient”及其方法,我正在包装它们。 “DashNetMsg.h”是一个头文件,字面上只包含上述结构定义。以下是 DashboardClient.Recv 方法的定义,来自 DashboadClient.cpp:

DashNetMsg DashboardClient::Recv() {
  DashNetMsg ret;
  if (Recv(&ret)) {
    // Indicate a null message
    strcpy(ret.type, "NullMessage");
  }

  return ret;
}

当我编译它并将其加载到 python 中时,出现了两个有趣且(我认为)相互关联的问题:

Python 3.1.3 (r313:86834, Nov 28 2010, 10:01:07) 
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import DashboardClient
>>> d = DashboardClient.DashboardClient()
>>> m = d.Recv()
>>> m
<Swig Object of type 'DashNetMsg *' at 0x7f4d4fc2d3c0>
>>> m.type
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'SwigPyObject' object has no attribute 'type'
>>> exit()
swig/python detected a memory leak of type 'DashNetMsg *', no destructor found.

首先,DashNetMsg 显然确实定义了一个名为“类型”的属性。其次,这个内存泄漏是怎么回事?根据 SWIG:

SWIG creates default constructor and destructor functions if none are defined in the interface.

(http://www.swig.org/Doc2.0/SWIG.html,第 5.5 节)

这是否意味着它应该为这个包装类型创建一个析构函数? 另外,为什么我不能访问我的结构的属性?

无效的解决方案

我认为可以解释正在发生的事情的最佳猜测是 SWIG 出于某种原因实际上并未包装 DashNetMsg 结构,而是将其视为不透明指针。因为 SWIG 似乎表明释放这些指针指向的内容必须手动完成,所以我猜它也可以解释内存泄漏。但是,即使是这种情况,我也不明白为什么 SWIG 不包装结构。

我读了here该 swig 必须具有声明为 C 风格的结构才能识别它们。因此,我尝试了这个:

typedef struct DashNetMsg {
  uint64_t timestamp;
    char type[64];
    char message[1024];
} DashNetMsg;

结果和上面的完全一样。

最佳答案

使用 SWIG 按值返回 struct 很棘手。 From their documentation :

C functions that return structures or classes datatypes by value are more difficult to handle...SWIG only really supports pointers.

SWIG allocates a new object and returns a reference to it. It is up to the user to delete the returned object when it is no longer in use. Clearly, this will leak memory if you are unaware of the implicit memory allocation and don't take steps to free the result.

关于c++ - 包装和使用返回带有 SWIG 结构的函数的问题(python),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18731908/

相关文章:

android - Buildozer 0.32 无法构建

c++ - 移动数组指针不会改变起始地址

c++ - 如何在没有 "&"或 "*"的情况下为调用的方法提供正确的参数?

c++ - 在 Qt 中从字符串中提取参数,包括引用区域

C++:让 Boost 工作;关于包含路径和链接库的问题

c - c 中 char* 指针的算术给出错误

c++ - 固定不安全指针

c++ - 如何将原始音频数据写入使用Alsa Driver C++捕获的文件

python - 如何让Python相信int类型实际上是hex类型?

python - 对于 pandas 数据框中的特定单元格,删除列表的元素