【问题标题】:Higher-Order Programming Using Boost::Python使用 Boost::Python 进行高阶编程
【发布时间】:2012-02-27 21:55:41
【问题描述】:

所以,我有一个简单的事件库,用 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;

如您所见,函数setResponse 是问题所在。它需要一个函数传递给它,不幸的是,Boost::Python 在这种情况下没有应用它的转换器魔法。当像下面这样调用时:

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

它给出了这个错误:

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)>)

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

【问题讨论】:

  • +1 因为我认为 Boost::Python 是一个非常酷的想法。

标签: python boost functional-programming boost-python higher-order-functions


【解决方案1】:

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

然后将不同的 c++ 函数传递给基类setResponse,它将知道如何查找和调用bp::object 中的函数。如果要在不同的线程上调用事件,您还需要确保正确处理 python 的全局解释器锁,如下所述:boost.python not supporting parallelism?

【讨论】:

  • 谢谢!在阅读本文之前,我使用几乎相同的方法修复了它。我刚刚向 listener 添加了一个额外的模板参数,传入 python::object 而不是 boost::function,并使用 typedef 将其命名为 python_listener。像魅力一样工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-11
  • 2012-05-02
  • 2010-10-28
  • 1970-01-01
  • 2013-06-19
  • 2015-01-11
相关资源
最近更新 更多