<p>最简单的例子;请注意,由于<code>Base</code>不是纯虚拟的,所以它很复杂。我们开始了:</p>
<ol>
<li><p>baz.cpp公司:</p>
<pre><code>#include<string>
#include<boost/python.hpp>
using std::string;
namespace py=boost::python;
struct Base{
virtual string foo() const { return "Base.foo"; }
// fooBase is non-virtual, calling it from anywhere (c++ or python)
// will go through c++ dispatch
string fooBase() const { return foo(); }
};
struct BaseWrapper: Base, py::wrapper<Base>{
string foo() const{
// if Base were abstract (non-instantiable in python), then
// there would be only this->get_override("foo")() here
//
// if called on a class which overrides foo in python
if(this->get_override("foo")) return this->get_override("foo")();
// no override in python; happens if Base(Wrapper) is instantiated directly
else return Base::foo();
}
};
BOOST_PYTHON_MODULE(baz){
py::class_<BaseWrapper,boost::noncopyable>("Base")
.def("foo",&Base::foo)
.def("fooBase",&Base::fooBase)
;
}
</code></pre></li>
<li><p>酒吧.py</p>
<pre><code>import sys
sys.path.append('.')
import baz
class PyDerived(baz.Base):
def foo(self): return 'PyDerived.foo'
base=baz.Base()
der=PyDerived()
print base.foo(), base.fooBase()
print der.foo(), der.fooBase()
</code></pre></li>
<li><p>生成文件</p>
<pre><code>default:
g++ -shared -fPIC -o baz.so baz.cpp -lboost_python `pkg-config python --cflags`
</code></pre></li>
</ol>
<p>结果是:</p>
<pre><code>Base.foo Base.foo
PyDerived.foo PyDerived.foo
</code></pre>
<p>在这里您可以看到<code>fooBase()</code>(非虚拟c++函数)如何调用virtual<code>foo()</code>,无论是在c++还是python中,virtual<code>foo()</code>都解析为重写。你可以在c++中从基类派生一个类,它的工作原理是一样的。</p>
<p><strong>编辑(提取c++对象):</strong></p>
<pre><code>PyObject* obj; // given
py::object pyObj(obj); // wrap as boost::python object (cheap)
py::extract<Base> ex(pyObj);
if(ex.check()){ // types are compatible
Base& b=ex(); // get the wrapped object
// ...
} else {
// error
}
// shorter, thrwos when conversion not possible
Base &b=py::extract<Base>(py::object(obj))();
</code></pre>
<p>从<code>PyObject*</code>构造<code>py::object</code>,并使用<code>py::extract</code>查询python对象是否与您试图提取的内容匹配:<code>PyObject* obj; py::extract<Base> extractor(py::object(obj)); if(!extractor.check()) /* error */; Base& b=extractor();</code></p>