包装和使用返回带有 SWIG (python) 的结构的函数时出现问题
Problems wrapping and using a function that returns a struct with SWIG (python)
这应该是一个简单的过程,但它仍然让我躲避了几天。
我的情况如下:
我正在用SWIG包装一个相对简单的C++接口,所以我可以在Python上使用它。但是,由于其中一个方法返回自定义结构,其定义如下,因此问题很复杂:
struct DashNetMsg {
uint64_t timestamp;
char type[64];
char message[1024];
};
这是我用于完成此操作的SWIG接口文件:
%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显然定义了一个名为"type"的属性。其次,这个内存泄漏是怎么回事?根据SWIG的说法:
SWIG 创建默认构造函数和析构函数(如果没有) 在接口中定义。
(http://www.swig.org/Doc2.0/SWIG.html,第5.5节)
这是否意味着它应该为此包装类型创建一个析构函数?另外,为什么我无法访问结构的属性?
不起作用的解决方案
我可以解释正在发生的事情的最佳猜测是,由于某种原因,SWIG实际上并没有包装DashNetMsg结构,而是将其视为不透明的指针。因为 SWIG 似乎表明释放这些指针指向的内容必须手动完成,所以我想它也可以解释内存泄漏。但是,即使是这种情况,我也不明白为什么SWIG不会包装结构。
我在这里读到,swig 必须声明为 C 样式的结构才能识别它们。因此,我尝试了这个:
typedef struct DashNetMsg {
uint64_t timestamp;
char type[64];
char message[1024];
} DashNetMsg;
它的结果与上述完全相同。
使用 SWIG 按值返回 struct
s 很棘手。从他们的文档中:
按值返回结构或类数据类型的 C 函数更难处理......SWIG只真正支持指针。
SWIG 分配一个新对象并返回对该对象的引用。当返回的对象不再使用时,由用户来删除它。显然,如果您不知道隐式内存分配并且不采取措施来释放结果,这将泄漏内存。
- 使用不带参数的函数访问结构元素
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 链表,反向函数,数据结构
- 结构向量中自定义结构函数的内存使用
- C++ 中的嵌套结构函数
- 在结构函数之间传递文件路径 C++ 编辑:修复LNK2019错误
- 如何将值从外部传递到结构函数
- 如果存在具有不同参数的继承成员,为什么对 C++ 结构函数的调用不明确?
- C++结构函数的多个定义
- C++ 另一个标头中的结构函数给出"missing type specifier"
- 如何在C中找到结构/函数的父头文件
- C++二进制文件到结构函数
- C++ 将结构函数作为继承结构中函数的参数传递
- 如何在 main 之外的类中使用结构函数
- 在类中使用结构函数,在基类 c++ 中使用变量
- C++ 结构函数体调用另一个结构函数,同一个模块
- 是存储在对象中的类/结构函数
- Eclipse CDT 在从 std::map 访问时无法解析结构函数
- C++模板自身名称作为模板模板参数在同一模板结构函数内传递
- 如何使用真正的字符串类型来表示类结构函数中的字符串