swig python wrap c++ 指向多态类型的指针向量
Posted
技术标签:
【中文标题】swig python wrap c++ 指向多态类型的指针向量【英文标题】:swig python wrap c++ vector of pointers to polymorphic types 【发布时间】: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!")
【问题讨论】:
【参考方案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
类的条目添加到向量应该是直截了当的。
【讨论】:
以上是关于swig python wrap c++ 指向多态类型的指针向量的主要内容,如果未能解决你的问题,请参考以下文章
指向 swig(或 Boost::Python)中的成员的指针
Swig:将成员变量(指向值的指针)转换为 python 列表