How to use weak_ptr in swig?

前端 未结 1 615
感动是毒
感动是毒 2021-01-06 04:13

SWIG homepage says shared_ptr is specially handled, but weak_ptr not. Does it means weak_ptr supporting has some bug/issue in SWIG? If it\'s ok to use, how to use it? Can an

1条回答
  •  梦谈多话
    2021-01-06 04:52

    weak_ptr doesn't need any special support in SWIG to use.

    The operations that need special support in SWIG for shared_ptr are dereferencing and passing into functions. This is because you never directly dereference or create a weak_ptr. Instead when you're using it normally in C++ you would call the lock() member function to upgrade it to a full, retained shared_ptr or one of the other functions to query its state.

    So all you need to do in practice therefore is wrap weak_ptr like any other template and use the existing shared_ptr support in conjunction. For example:

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

    This can be exercised with some 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);
      }
    }
    

    When run this gives:

    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
    

    (Notice here that System.gc() has been completely ignored by my runtime, so the attempt to lock again does actually succeed)

    But it also works with the same .i file for the following Python:

    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
    

    And when run gives:

    g++ -Wall -Wextra -I/usr/include/python2.6 -std=c++0x -shared -o _test.so test_wrap.cxx && python run.py
     *' at 0xf7419710> >
     *' at 0xf7419728> >
     *' at 0xf7419740> >
    2
    1
    0
    None
    

    Where the reference counting instead of GC does result in the call to lock() failing after the last shared_ptr has no more references.

    0 讨论(0)
提交回复
热议问题