【问题标题】:swig python wrap c++ vector of pointers to polymorphic typesswig python wrap c++​​ 指向多态类型的指针向量
【发布时间】:2019-03-02 21:08:08
【问题描述】:

我有 2 个类(“Foo”、“Bar”),它们是从基类“Base”派生的,如下所示。

class Base{
public:
    virtual void basemethod() = 0 ;
};

class Base: public Foo{

    virtual void basemethod() ;
    void foo();
};

class Base: public Bar{
    virtual void basemethod() ;
    void bar();
};

还有另一个类创建了这些类的实例,如下所示

class Entity{
    std::vector<std::shared_ptr<Base> > Get();
};

我有下面的 idl 文件,但在这种情况下,在 python 代码中,我无法访问真实的类型信息

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

%template(MyVector) std::vector<std::shared_ptr<Base> >;

是否可以将此接口包装在 swig 中,以便下面的 python 代码按预期工作?

entity = Entity()
vec = entity.Get()

if isinstance(vec[0], Bar):
    print("this is a Bar!")

if isinstance(vec[1], Foo):
    print("this is a Foo!")

【问题讨论】:

    标签: python c++ swig


    【解决方案1】:

    你快到了……

    base.hpp

    #pragma once
    
    class Base{
     public:
      virtual void basemethod() = 0;
      virtual ~Base() = default;
      virtual const char* name() = 0;
    };
    

    衍生物.hpp

    #pragma once
    
    #include "base.hpp"
    
    class Foo : public Base {
      virtual void basemethod();
      void foo();
      const char* name();
    };
    
    class Bar : public Base {
      virtual void basemethod();
      void bar();
      const char* name();
    };
    

    实体.hpp

    #include <memory>
    #include <vector>
    #include "base.hpp"
    
    class Entity {
     public:
      static std::vector<std::shared_ptr<Base> > Get();
    };
    

    衍生物.cpp

    #include "derivatives.hpp"
    
    void Foo::basemethod() {
    }
    void Foo::foo() {
    }
    
    const char* Foo::name() {
      static char name[] = "Foo";
      return name;
    }
    
    void Bar::basemethod() {
    }
    void Bar::bar() {
    }
    
    const char* Bar::name() {
      static char name[] = "Bar";
      return name;
    }
    

    实体.cpp

    #include "entity.hpp"
    #include "derivatives.hpp"
    
    std::vector<std::shared_ptr<Base> > Entity::Get() {
        std::vector<std::shared_ptr<Base> > vec;
        std::shared_ptr<Base> base = std::make_shared<Foo>();
        vec.push_back(base);
        return vec;
    }
    

    example.i

    %module example
    %{
      #include "base.hpp"
      #include "derivatives.hpp"
      #include "entity.hpp"
    %}
    
    %include "std_vector.i"
    %include "std_shared_ptr.i"
    
    %shared_ptr(Base);
    %shared_ptr(Foo);
    %shared_ptr(Bar);
    
    %template(BaseVector) std::vector<std::shared_ptr<Base> >;
    
    %include "base.hpp"
    %include "derivatives.hpp"
    %include "entity.hpp"
    
    %extend Base {
    %pythoncode %{
      def __instancecheck__(self, other):
        return self.name() == other.name()
    %}
    };
    

    编译完成后,可以在Python中进行如下操作

    import example
    hmm = example.Entity_Get()
    isinstance(hmm[0], example.Foo())
    

    Bar 类的条目添加到向量应该是直截了当的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-09-10
      • 2011-08-04
      • 1970-01-01
      • 2020-04-13
      • 1970-01-01
      • 2011-12-09
      • 1970-01-01
      相关资源
      最近更新 更多