我有一个C++类层次结构,我通过SWIG暴露给Python。公开的类由std::shared_ptr
包装。你知道吗
我遇到的问题是Python没有公开作为基std::shared_ptr
返回的派生对象上的方法。这是令人惊讶的,因为运行时似乎能够推断出对象的类型是派生的std::shared_ptr
。你知道吗
当显式返回派生的std::shared_ptr
时,我可以看到派生的方法。你知道吗
问题here表明,我所要做的事情可以通过使用带有typemap声明的原始指针来实现。你知道吗
我的项目h:
#pragma once
#include <memory>
#include <vector>
#include <exception>
namespace MyProg
{
enum SubTypes
{
BaseType,
DerivedAType,
DerivedBType
};
class Base
{
public:
virtual SubTypes SubType()
{
return BaseType;
}
virtual ~Base() {}
protected:
Base() {}
};
class DerivedA : public Base
{
public:
friend class MyProg;
int CallDerivedA()
{
return 1;
}
SubTypes SubType()
{
return DerivedAType;
}
private:
DerivedA() : Base() {}
};
class DerivedB : public Base
{
public:
friend class MyProg;
int CallDerivedB()
{
return 2;
}
SubTypes SubType()
{
return DerivedBType;
}
private:
DerivedB() : Base()
{}
};
typedef std::shared_ptr<Base> BasePtr;
typedef std::shared_ptr<DerivedA> DerivedAPtr;
typedef std::shared_ptr<DerivedB> DerivedBPtr;
class MyProg
{
public:
MyProg()
{
// Create instances
m_derivedA = std::shared_ptr<Base>(new DerivedA());
m_derivedB = std::shared_ptr<Base>(new DerivedB());
}
DerivedAPtr GetDerivedA()
{
return std::dynamic_pointer_cast<DerivedA>(m_derivedA);
}
DerivedBPtr GetDerivedB()
{
return std::dynamic_pointer_cast<DerivedB>(m_derivedB);
}
BasePtr GetDerived(const SubTypes subType)
{
if (subType == DerivedAType)
{
return m_derivedA;
}
else if (subType == DerivedBType)
{
return m_derivedB;
}
throw std::exception("Unsupported type requested");
}
private:
BasePtr m_derivedB;
BasePtr m_derivedA;
};
}
SWIG接口:
%module MyProg_Python
%include "typemaps.i"
%include <cpointer.i>
%include <std_shared_ptr.i>
%shared_ptr(MyProg::Base);
%shared_ptr(MyProg::DerivedA);
%shared_ptr(MyProg::DerivedB);
// I created this typemap based on the code generated for the GetDerivedA and GetDerivedB functions
%typemap(out) MyProg::Base {
if (($1)->SubType() == MyProg::DerivedAType)
{
std::shared_ptr< MyProg::DerivedA > myptr = std::dynamic_pointer_cast< MyProg::DerivedA >(result);
std::shared_ptr< MyProg::DerivedA > *smartresult = result ? &myptr : 0;
$result = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_MyProg__DerivedA_t, SWIG_POINTER_OWN);
}
else if (($1)->SubType() == MyProg::DerivedBType)
{
std::shared_ptr< MyProg::DerivedB > myptr = std::dynamic_pointer_cast< MyProg::DerivedB >(result);
std::shared_ptr< MyProg::DerivedB > *smartresult = result ? &myptr : 0;
$result = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_MyProg__DerivedB_t, SWIG_POINTER_OWN);
}
else
{
// error
}
}
%{
#include "MyProg.h"
using namespace std;
using namespace MyProg;
%}
%include "..\MyProg\MyProg.h"
namespace MyProg
{
typedef std::shared_ptr<Base> BasePtr;
typedef std::shared_ptr<DerivedA> DerivedAPtr;
typedef std::shared_ptr<DerivedB> DerivedBPtr;
}
Python客户端:
from MyProg_Python import *
prog = MyProg()
a = prog.GetDerivedA()
result = a.CallDerivedA() # returns 1
b = prog.GetDerivedB()
result = b.CallDerivedB() # returns 2
afrombase = prog.GetDerived(DerivedAType)
# The following line doesn't resolve, even though runtime indicates afrombase is of type MyProg_Python.DerivedA (proxy of <Swig Object of type 'std::shared_ptr<MyProg::DerivedA> * ' at 0x...>)
afrombase.CallDerivedA()
这是对共享指针的限制吗-我需要使用原始指针吗?或者是否有一个typemap声明允许我在Python中公开多态行为?你知道吗
目前没有回答
相关问题 更多 >
编程相关推荐