Swig导演和Python中的智能指针

时间:2018-01-11 11:36:57

标签: python-3.x c++11 swig

使用Swig尝试将智能指针包装到Python中的导向器类时,我遇到了一些问题。我知道文档说支持有限,但我想知道Swig是否支持我的场景。

简而言之,如果导演类在Python中扩展并作为智能指针传递,那么当Python对象死亡时,内存区域就会消失。如果使用__disown__来防止这种情况,则会发生内存泄漏(另请参阅http://swig.10945.n7.nabble.com/Using-director-shared-pointer-disown-gt-memory-leak-td11821.html)。

以下是显示问题的最小示例。

example.h文件:

#ifndef EXAMPLE_H
#define EXAMPLE_H

#include <string>
#include <memory>

namespace example
{

class ContentBase
{
public:
    ContentBase() {}

    virtual ~ContentBase() {}

    virtual std::string get_name() { return "ContentBase " + m_name; }

    virtual void set_name(const std::string& name) { m_name = name; }

private:
    std::string m_name;
};

class Container
{
public:
    Container() {}

    void set_content(std::shared_ptr<ContentBase> content) { m_content = content; }

    std::shared_ptr<ContentBase> get_content() { return m_content; }

private:
    std::shared_ptr<ContentBase> m_content;
};

} // namespace example

#endif /* EXAMPLE_H */

example.i:

%module(directors="1") example

%include "std_string.i"
%include <std_shared_ptr.i>

%{
#include "example.h"
%}

%shared_ptr(example::ContentBase)
%feature("director") example::ContentBase;

%include "example.h"

test_example.py:

import pytest

import example as e

class PyContent(e.ContentBase):
    def __init__(self, *args, **kwargs):
        e.ContentBase.__init__(self, *args, **kwargs)
        self.name = "empty"
        #self.__disown__()

    def get_name(self):
        return "py " + self.name

    def set_name(self, n):
        self.name = n

def set_python_content(container):
    content = PyContent()
    content.set_name("content")
    container.set_content(content)

    content2 = container.get_content()
    assert content2.get_name() == "py content"

def test_python_inheritance():
    container = e.Container()
    set_python_content(container)

    content = container.get_content()
    assert content.get_name() == "py content"

只要至少有一个Python引用或共享指针处于活动状态(并且没有内存泄漏),是否有办法使ContentBase保持活动状态?

注意:我使用的是Swig 3.0.12,但即使使用从Github编译的最新版本(c44adff7b9f5dc675d7c2dbbf4ea36660c3b1466),也会出现相同的行为。

0 个答案:

没有答案