使用Boost :: Python进行高阶编程

Sam*_*ese 6 python boost functional-programming boost-python higher-order-functions

所以,我有一个简单的事件库,用C++编写并使用Boost库.我想把这个库暴露给Python,所以很自然地我转向了Boost :: Python.我最终得到了编译代码,但现在我遇到了相当严重的问题:我的库使用了高阶编程技术.例如,库由三个主要类组成:事件类,事件管理器类和事件侦听器类.事件监听器类带来了问题.码:

    class listener{
        public:
            listener(){}
            void alert(cham::event::event e){
                if (responses[e.getName()])
                    responses[e.getName()](e.getData());
            }
            void setResponse(std::string n, boost::function<void (std::string d)> c){responses.insert(make_pair(n, c));}
            void setManager(_manager<listener> *m){manager = m;}
        private:
            std::map<std::string, boost::function<void (std::string d)> > responses;
            _manager<listener> *manager;
Run Code Online (Sandbox Code Playgroud)

如您所见,功能setResponse就是问题所在.它需要一个函数传递给它,不幸的是,在这种情况下,Boost :: Python不会应用它的转换器魔法.如下所示调用时:

>>> import chameleon
>>> man = chameleon.manager()
>>> lis = chameleon.listener()
>>> def oup(s):
...  print s
... 
>>> lis.setResponse("event", oup)
Run Code Online (Sandbox Code Playgroud)

它给出了这个错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Boost.Python.ArgumentError: Python argument types in
    listener.setResponse(listener, str, function)
did not match C++ signature:
    setResponse(cham::event::listener {lvalue}, std::string, boost::function<void ()(std::string)>)
Run Code Online (Sandbox Code Playgroud)

所以,我的问题是,我该如何解决这个问题?它必须使用重载或包装器,因为我希望库可以通过C++保持可调用.

Mat*_*ten 2

您将需要一个围绕 的包装器setResponse,它采用 aboost::python::object而不是函数。它应该将其存储bp::object在已知位置(可能是listener子类的成员变量)。

然后将一个不同的 C++ 函数传递给 base setResponse,它将知道如何查找和调用bp::object. 如果要在不同的线程上调用事件,您还需要确保正确处理 python 的全局解释器锁,如下所述:boost.python 不支持并行性?