我有一个使用大量类的 C++ 项目。主要的是'sso::Object
'(每个类都在'sso'命名空间中)并且这个类被派生到一些其他类但是一个是抽象的:'sso::可绘制
'。
这个类有两个纯虚方法 'sso::Drawable::set_opacity
' 和 'sso::Drawable::raw_draw
' 并且派生到其他类像 'sso::View
' 实现了这两个方法。
整个项目在 C++ 中使用时工作正常,但我也想在 Python 中使用它,所以我创建了一个这样的 Boost.Python 模块:
class DrawableWrapper : public sso::Drawable , public wrapper<sso::Drawable> {
public:
void set_opacity(byte opacity) { this->get_override("set_opacity")(opacity); }
void raw_draw(const sso::Rect &rect,sso::Target &target,const sso::Position &position) const {
this->get_override("raw_draw")(rect,target,position);
}
};
BOOST_PYTHON_MODULE(sso) {
class_<DrawableWrapper,boost::noncopyable> ("Drawable",init<>())
.add_property ("opacity",&sso::Drawable::get_opacity)
// python_sso_getter & python_sso_setter_* are only used for an easier access to accessors
.add_property ("position",python_sso_getter<sso::Drawable,sso::Position,&sso::Drawable::get_position>,python_sso_setter_1_const<sso::Drawable,sso::Position,&sso::Drawable::set_position>)
.def("raw_draw",pure_virtual(&sso::Drawable::raw_draw))
;
class_<sso::View,bases<sso::Drawable> > ("View",init<>())
.def("insert",python_sso_setter_1<sso::View,sso::Drawable*,&sso::View::insert>)
.def("remove",&sso::View::erase)
;
}
这段代码编译没有错误,但是当我在 Python 中执行这些行时:
myview = sso.View()
print myview
我得到这个输出:
<sso.View object at 0x7f9d2681a4b0>
但是我的 C++ 调试器告诉我变量“v”(python 的“myview”)是一个“sso::Object
”实例,而不是一个“sso::View<”/
'一个。 sso::View::View()
被调用但变量类型不是 View ,我不知道为什么。你知道吗?您是否做过类似的事情并找到了让它发挥作用的方法?
我使用 Python2.7 和 Boost.Python1.49 以及 gcc 版本 4.6.1
编辑:我犯了一个错误:sso::Drawable
不是继承自 sso::Object
,而是继承自 sso::View
确实(=多重继承)。
最佳答案
输出 <sso.View object at 0x7f9d2681a4b0>
来自 python 只是 python 告诉你它认为对象类型被称为什么,它与在 C++ 级别创建的对象的实际类型无关。
正如您告诉 boost python 将对象公开为 sso.View
那么这就是 python 将其视为的内容。如果您要更改代码以公开 std::string
作为sso.View
那么 python 仍然会报告 <sso.View object at 0x7f9d2681a4b0>
在你创建它之后。
同样,如果您要更改 "View"
在你的 C++ 中为 "BlahDeBlah"
然后 python 会将对象报告为 <sso.BlahDeBlah object at 0x7f9d2681a4b0>
(当然你还必须通过 sso.BlahDeBlah()
除此之外,我看不出您发布的代码有任何问题。是否sso::View
继承自 sso::Object
?如果是这样,并且您已经目睹了sso::view::View()
被调用,那么我认为当调试器告诉您对象类型为 sso::Object
时,您可能只是误解了调试器。 .也许在您调试时它有指向基类或类似内容的指针?
当您调用 myview.insert
时会发生什么或 myview.remove
来自 python?
编辑:我怀疑(虽然我可能是错的)你可能没有在你的编译器中打开 RTTI,所以 typeid()
只是返回实现您调用时所在函数的类型 typeid()
.这肯定可以解释为什么你得到 sso::View
当在 insert
但在其他功能中有不同的答案。
无论如何,我仔细研究了文档,我认为您的问题实际上是您提供了覆盖 raw_draw
的能力。方法,但您实际上并没有用任何东西覆盖它。
如果你看一下 pure_virtual
的减速boost::python 函数 at the bottom of this file你会看到一条评论:
//
// Passed a pointer to member function, generates a def_visitor which
// creates a method that only dispatches to Python if the function has
// been overridden, either in C++ or in Python, raising a "pure
// virtual called" exception otherwise.
//
所以您所看到的只是预期的行为。如果您为 raw_draw
提供覆盖在 sso::View
或者从它继承的 python 类,那么你应该不会再得到这个错误。
关于c++ - 如何使用 Boost.Python 从 C++ 对象创建 Python 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11308747/