如何在swig中使用weak_ptr? [英] How to use weak_ptr in swig?

查看:153
本文介绍了如何在swig中使用weak_ptr?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

SWIG主页说shared_ptr是专门处理的,但是weak_ptr没有。这是否意味着weak_ptr支持在SWIG中存在一些错误/问题?如果可以使用,如何使用它?任何人都可以提供样品.i代码吗?非常感谢。

解决方案

weak_ptr 不需要任何特别支持在SWIG中使用。



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



所以你需要在实践中做的就是像任何其他模板一样包装 weak_ptr 并使用现有的 shared_ptr 支持。例如:

 %module test 

%{
#include< memory>
%}

%包括< 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&);
模板< class其他>
weak_ptr(const weak_ptr< Other>&);
模板< class其他>
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 {};
%}
%模板(FooWeakPtr)std :: weak_ptr< Foo> ;;

这可以用一些Java行使:



< pre class =lang-java prettyprint-override> 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()
打印

b = test.FooWeakPtr(a)
打印b

c = b.lock()
打印c

打印b.use_count ()
a =无
打印b.use_count()
c =无
打印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;代理< Swig对象类型'std :: shared_ptr< Foo> *'在0xf7419710> >
< test.FooWeakPtr;代理< Swig对象类型'std :: weak_ptr< Foo> *'在0xf7419728> >
< test.Foo;代理< Swig对象类型'std :: shared_ptr< Foo> *'在0xf7419740> >
2
1
0

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


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 anybody please give a sample .i code? Thanks very much.

解决方案

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 <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>;

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
<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

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

这篇关于如何在swig中使用weak_ptr?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆