简体   繁体   English

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

[英]Higher-Order Programming Using Boost::Python

So, I have a simple event library, written in C++ and using the Boost libraries. 所以,我有一个简单的事件库,用C ++编写并使用Boost库。 I wanted to expose said library to Python, so naturally I turned to Boost::Python. 我想把这个库暴露给Python,所以很自然地我转向了Boost :: Python。 I got the code to compile, eventually, but now I'm faced with quite the problem: my library uses higher-order programming techniques. 我最终得到了编译代码,但现在我遇到了相当严重的问题:我的库使用了高阶编程技术。 For example, the library is made up of three main classes: an event class, an event manager class, and an event listener class. 例如,库由三个主要类组成:事件类,事件管理器类和事件侦听器类。 The event listener class poses a problem. 事件监听器类带来了问题。 Code: 码:

    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;

As you can see, the function setResponse is the problem. 如您所见,函数setResponse就是问题所在。 It requires a function to be passed to it, and, unfortunately, Boost::Python does not apply it's converter magic in this situation. 它需要一个函数传递给它,不幸的是,在这种情况下,Boost :: Python不会应用它的转换器魔法。 When called like the following: 如下所示调用时:

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

it gives this error: 它给出了这个错误:

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

So, my question is, how could I fix this? 所以,我的问题是,我该如何解决这个问题? It would have to either use overloading or a wrapper, as I would like the library to remain callable by C++. 它必须使用重载或包装器,因为我希望库可以通过C ++保持可调用。

You will need a wrapper around setResponse , which takes a boost::python::object instead of a function. 你需要一个围绕setResponse的包装器,它需要一个boost::python::object而不是一个函数。 It should store this bp::object in a known location (probably a member variable of a listener subclass). 它应该将此bp::object存储在已知位置(可能是listener子类的成员变量)。

Then pass a different c++ function to the base setResponse , that will know how to lookup and call the function in the bp::object . 然后将一个不同的c ++函数传递给基本setResponse ,它将知道如何在bp::object查找和调用该函数。 If events are to be called on a different thread, you will also need to ensure proper handling of python's Global Interpreter Lock, as discussed here: boost.python not supporting parallelism? 如果要在不同的线程上调用事件,您还需要确保正确处理python的Global Interpreter Lock,如下所述: boost.python不支持并行性? .

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM