可能是重复问题:
使用boost::python将回调从Python传递到C++
我需要将一个Python函数作为C++函数的回调。如何实现?有没有一些示例可以参考?我想使用boost.python。
可能是重复问题:
使用boost::python将回调从Python传递到C++
我需要将一个Python函数作为C++函数的回调。如何实现?有没有一些示例可以参考?我想使用boost.python。
我通常用以下方法(并不是唯一的方法)来实现回调函数:
在C++中,我使用一个类来提供以下方式的回调函数:
struct Mesh {
template<class Visitor>
void visitChildren(Visitor& v)
{
[...]
v.visit([...])
}
}
然后当我将这个类导出到Python(仍然是C ++)时
struct ChildrenVisitor
{
ChildrenVisitor(PyObject* self)
: self(self)
{}
void visit( /* .... */ )
{
call_method<void>(self, "visit" /*, [...] */ );
}
private:
PyObject* self; // 1
};
typedef ChildrenVisitor ClassT;
class_<ClassT, boost::noncopyable >("ChildrenVisitor",
init<PyObject*>() );
对于Mesh
的导出,你需要执行以下操作:
.def("visitChildren", &Mesh::template visitChildren<ChildrenVisitor> )
我通常使用...
,这里可以插入任何参数。
在Python中,你可以这样做:
class MyVisitor(ChildrenVisitor):
def __init__(self):
ChildrenVisitor.__init__(self,self)
def visit(self):
# do whatever you want
ChildrenVisitor
的子类,它接受Lambda函数,这使得在Python中编写访问者只需要一行代码。
struct ChildrenVisitorBase
{
virtual void visit( /* .... */ ) = 0;
};
struct Mesh {
void registerCallback(shared_ptr<ChildrenVisitorBase> v)
{
visitors.push_back(v)
}
void doSomeWork() {
// ...
for(int i=0; i < visitors.size(); ++i)
visitors[i]->visit( /* ... */ )
}
std::vector< shared_ptr<ChildrenVisitorBase> > visitors;
}
ChildrenVisitor
实现 ChildrenVisitorBase
接口。你的问题可以在这个示例中找到答案。
如果你想要作为回调函数的函数在编译时已知,那么应该使用PyEval_CallObject(...);
。如果函数必须在运行时定义,则使用示例中所示的方案来接收函数指针。