我遇到了SWIG,共享指针和继承问题.
我正在使用创建各种继承的c类
提升共享指针以引用它们,然后将这些共享包装起来
使用SWIG创建python类的指针.
我的问题如下:
> B是A的子类
> sA是指向A的共享指针
> sB是指向B的共享指针
> f(sA)是一个期望共享指向A的函数
>如果我将sB传递给f(),则会引发错误.
>此错误仅发生在python级别.
>在C级别,我可以毫无问题地将sB传递给f().
我有提升1.40和swig 1.3.40.
python setup.py build_ext --inplace python test.py
swig_shared_ptr.h
#ifndef INCLUDED_SWIG_SHARED_PTR_H #define INCLUDED_SWIG_SHARED_PTR_H #include <boost/shared_ptr.hpp> class Base {}; class Derived : public Base {}; typedef boost::shared_ptr<Base> base_sptr; typedef boost::shared_ptr<Derived> derived_sptr; void do_something (base_sptr bs); base_sptr make_base(); derived_sptr make_derived(); #endif
swig_shared_ptr.cc
#include <iostream> #include "swig_shared_ptr.h" void do_something (base_sptr bs) { std::cout << "Doing something." << std::endl; } base_sptr make_base() { return base_sptr(new Base ()); }; derived_sptr make_derived() { return derived_sptr(new Derived ()); };
swig_shared_ptr.i
%module(docstring=" Example module showing problems I am having with SWIG,shared pointers and inheritance. ") swig_shared_ptr %{ #include "swig_shared_ptr.h" %} %include <swig_shared_ptr.h> %include <boost_shared_ptr.i> %template(base_sptr) boost::shared_ptr<Base>; %template(derived_sptr) boost::shared_ptr<Derived>;
setup.py
""" setup.py file for swig_shared_ptr """ from distutils.core import setup,Extension swig_shared_ptr_module = Extension('_swig_shared_ptr',include_dirs = ['/usr/include/boost'],sources=['swig_shared_ptr.i','swig_shared_ptr.cc'],) setup (name = 'swig_shared_ptr',version = '0.1',author = "Ben",description = """Example showing problems I am having with SWIG,shared pointers and inheritance.""",ext_modules = [swig_shared_ptr_module],py_modules = ["swig_shared_ptr"],)
test.py
import swig_shared_ptr as ssp bs = ssp.make_base() dr = ssp.make_derived() # Works fine. ssp.do_something(bs) # Fails with "TypeError: in method 'do_something',argument 1 of type 'base_sptr'" ssp.do_something(dr)
解决方法
以下更改似乎可以解决问题.
在swig_shared_ptr.i中有两行:
%template(base_sptr) boost::shared_ptr<Base>; %template(derived_sptr) boost::shared_ptr<Derived>;
被移动,以便它们在线上方
%include <swig_shared_ptr.h>
然后通过以下方式替换(在SWIG 1.3中):
SWIG_SHARED_PTR(Base,Base) SWIG_SHARED_PTR_DERIVED(Derived,Base,Derived)
或(在SWIG 2.0中):
%shared_ptr(Base) %shared_ptr(Derived)