python的std函数_使用boost :: python公开具有std :: function作为参数的C ++成员函数

本文介绍了如何使用Boost.Python库将C++类中的std::function属性暴露给Python,并允许Python对象作为回调函数。通过创建一个辅助函数,可以避免Boost.Python在运行时查找std::function转换器,从而成功地从Python调用C++的SetCallbackFunction方法。
摘要由CSDN通过智能技术生成

I have a class that contains an attribute which is a std::function. I set the value of this attribute using a member function, so the class looks like this:

class ClassName

{

public:

void SetCallbackFunction(std::function callbackFun) {

m_callbackFunction = callbackFun;

}

protected:

std::function m_callbackFunction;

};

I need to expose this class to Python and, of course, I need to expose the SetCallbackFunction function.

How can I do this with boost::python?

解决方案

As Python objects are both Callable and CopyConstructible, the simplest approach is to expose an auxiliary function as SetCallbackFunction that accepts a boost::python::object, then delegates to the actual SetCallbackFunction function:

void ClassName_SetCallbackFunction_aux(ClassName& self, boost::python::object object)

{

self.SetCallbackFunction(object);

}

BOOST_PYTHON_MODULE(example)

{

namespace python = boost::python;

python::class_("ClassName", python::init<>())

.def("set_callback", &ClassName_SetCallbackFunction_aux)

// ...

;

}

When ClassName::SetCallbackFunction is directly exposed to Python and invoked, Boost.Python will search its registry at runtime to locate a from-Python converter for std::function. As this conversion has not been explicitly registered, Boost.Python will fail to dispatch the function call. The auxiliary function avoids this runtime conversion check and constructs a std::function object from a boost::python::object, as the boost::python::object is both Callable and CopyConstructible.

Here is an example demonstrating using an auxiliary function to assign Python objects as callbacks:

#include // std::function

#include

// Legacy API.

class spam

{

public:

void SetCallbackFunction(std::function callback)

{

callback_ = callback;

}

void perform(int x)

{

callback_(x);

}

private:

std::function callback_;

};

BOOST_PYTHON_MODULE(example)

{

namespace python = boost::python;

// Expose spam.

python::class_("Spam", python::init<>())

// Use an auxiliary function to set Python callbacks.

.def("set_callback", +[](spam& self, boost::python::object object) {

self.SetCallbackFunction(object);

})

.def("perform", &spam::perform)

;

}

Interactive usage:

>>> import example

>>> called = False

>>> def perform_x(x):

... assert(42 == x)

... global called

... called = True

...

>>> spam = example.Spam()

>>> spam.set_callback(perform_x)

>>> assert(not called)

>>> spam.perform(42)

>>> assert(called) # Verify callback was invoked

>>> spam.set_callback(lambda: None)

>>> try:

... spam.perform(42)

... assert(False) # Verify callback fails (the lambda accepts no args)

... except TypeError:

... pass

...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值