我使用SWIG向Python公开了以下c++类(简化版):
struct Component
{
virtual void update();
}
struct DerivedComponent : public Component
{
void update() { cout << "DerivedComponent::update()" << endl; }
void speak() { cout << "DerivedComponent::speak()" << endl; }
}
class Entity
{
public:
Component* component(const std::string& class_name)
{
return m_components[class_name];
}
private:
std::unordered_map<std::string, Component*> m_components;
}
现在,在Python中,我可以成功地在实体实例上调用component("DerivedComponent").update()
。但是,我不能调用component("DerivedComponent").speak()
,因为component("DerivedComponent")
返回的类型被报告为<class 'module.Component'>
。在
我显然需要下推component()
函数的结果,以便调用DerivedComponent
中定义的方法。我原本希望斯威格能像我所相信的那样,执行自动降速Boost.Python做。在
除了在c++中定义一大堆类型转换函数并将它们公开给Python之外,有没有更好的方法来使用Swig或Python进行向下转换呢?我有什么选择?在
在Python中,只需做一点工作,就可以完成您想要的事情。它如您所希望的那样工作,因为在Python中,由于函数的返回类型(或通常的类型)不是强类型的,因此我们可以修改您的
Entity::component
函数以始终返回最派生的类型,而不管它是什么。在为用C++ + Python绑定实现这项工作,您需要为^ {CD1>}编写一个“OUT”类型映射。我写了一个例子来说明它的工作原理。在这种情况下,我们必须稍微预兆一下,因为知道将它向下转换到什么位置的唯一方法来自函数的参数。(例如,如果基类有一个以字符串/枚举形式返回的方法,则可以进一步简化该方法,而不依赖于输入参数)。在
这使用
SWIG_TypeQuery
函数要求Python运行时基于arg2查找类型(在您的示例中是字符串)。在我必须对你的示例标题(名为测试.hh在我的示例中)为了在我将其制作成一个完全正常工作的演示之前解决一些问题,它最终看起来像:
^{pr2}$然后我用:
^{3}$有了这一点,我可以运行以下Python:
正如您所希望的那样:
我想做一些类似的事情,并基于this question提出了一个类似但不同的解决方案。在
如果您提前知道了可能的类型,并且不介意额外的开销,那么您可以让“out”typemap循环通过并对每个类型进行动态转换,以自动返回带有其实际类型的对象。SWIG已经为具有%factory特性的指针实现了此功能:
看着工厂.swg还有boost_-part-ptr。我把这个应用于shared-u-ptr和dynamic-tu-pointer-cast:
^{pr2}$相关问题 更多 >
编程相关推荐