【问题标题】:How to use weak_ptr in swig?如何在 swig 中使用weak_ptr?
【发布时间】:2014-07-17 12:08:50
【问题描述】:

SWIG 主页说 shared_ptr 是经过特殊处理的,但 weak_ptr 不是。这是否意味着 weak_ptr 支持在 SWIG 中有一些错误/问题?如果可以用,怎么用?任何人都可以提供一个示例 .i 代码吗?非常感谢。

【问题讨论】:

    标签: java swig weak-ptr


    【解决方案1】:

    weak_ptr 不需要 SWIG 中的任何特殊支持即可使用。

    在 SWIG 中需要为 shared_ptr 提供特殊支持的操作是取消引用并传递给函数。这是因为您从不直接取消引用或创建weak_ptr。相反,当您在 C++ 中正常使用它时,您将调用 lock() 成员函数将其升级为完整的、保留的 shared_ptr 或其他函数之一来查询其状态。

    因此,您在实践中需要做的就是像任何其他模板一样包装weak_ptr,并结合使用现有的shared_ptr 支持。例如:

    %module test
    
    %{
    #include <memory>
    %}
    
    %include <std_shared_ptr.i>
    
    %shared_ptr(Foo)
    
    namespace std {
    template<class Ty> class weak_ptr {
    public:
        typedef Ty element_type;
    
        weak_ptr();
        weak_ptr(const weak_ptr&);
        template<class Other>
            weak_ptr(const weak_ptr<Other>&);
        template<class Other>
            weak_ptr(const shared_ptr<Other>&);
    
        weak_ptr(const shared_ptr<Ty>&);
    
    
        void swap(weak_ptr&);
        void reset();
    
        long use_count() const;
        bool expired() const;
        shared_ptr<Ty> lock() const;
    };
    }
    
    %inline %{
        struct Foo { };
    %}
    %template(FooWeakPtr) std::weak_ptr<Foo>;
    

    这可以通过一些 Java 来实现:

    public class run {
      public static void main(String[] argv) {
        System.loadLibrary("test");
    
        Foo a = new Foo();
        System.out.println(a);
    
        FooWeakPtr b=new FooWeakPtr(a);
        System.out.println(b);
    
        Foo c=b.lock();
        System.out.println(c);
    
        System.out.println(b.use_count());
        a=null;
        System.gc();
        System.out.println(b.use_count());
        c=null;
        System.gc();
        System.out.println(b.use_count());
    
        Foo d=b.lock();
        System.out.println(d);
      }
    }
    

    运行时给出:

    swig2.0 -c++ -Wall -java test.i && g++ -Wall -Wextra -I/usr/lib/jvm/java-6-sun/include -I/usr/lib/jvm/java-6-sun/include/linux -std=c++0x -shared -o libtest.so test_wrap.cxx && javac run.java && LD_LIBRARY_PATH=. java run
    Foo@42719c
    FooWeakPtr@119298d
    Foo@f72617
    2
    2
    2
    Foo@dc8569
    

    (请注意,System.gc() 已被我的运行时完全忽略,因此再次尝试锁定确实成功)

    但它也适用于以下 Python 的相同 .i 文件:

    import test
    
    a=test.Foo()
    print a
    
    b=test.FooWeakPtr(a)
    print b
    
    c=b.lock()
    print c
    
    print b.use_count()
    a=None
    print b.use_count()
    c=None
    print b.use_count()
    
    d=b.lock()
    print d
    

    当运行给出:

    g++ -Wall -Wextra -I/usr/include/python2.6 -std=c++0x -shared -o _test.so test_wrap.cxx && python run.py
    <test.Foo; proxy of <Swig Object of type 'std::shared_ptr< Foo > *' at 0xf7419710> >
    <test.FooWeakPtr; proxy of <Swig Object of type 'std::weak_ptr< Foo > *' at 0xf7419728> >
    <test.Foo; proxy of <Swig Object of type 'std::shared_ptr< Foo > *' at 0xf7419740> >
    2
    1
    0
    None
    

    在最后一个 shared_ptr 没有更多引用之后,引用计数而不是 GC 确实会导致对 lock() 的调用失败。

    【讨论】:

      猜你喜欢
      • 2021-12-19
      • 2018-06-08
      • 2020-02-16
      • 1970-01-01
      • 2019-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多