Higher order programming with Boost :: Python

So, I have a simple event library written in C ++ and using Boost libraries. I wanted to expose the specified library in Python, so I naturally turned to Boost :: Python. I got the code to compile in the end, but now I run into a problem: my library uses higher-order programming methods. For example, a library consists of three main classes: an event class, an event dispatcher class, and an event listener class. The event listener class poses a problem. The 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 setResponse function is a problem. It requires a function to be passed to it, and unfortunately Boost :: Python does not apply this converting magic in this situation. When called like this:

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

he 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 can I fix this? This would have to either use overloading or the shell, since I would like the library to remain C ++ callable.

+6
source share
1 answer

You will need a wrapper around setResponse , which, instead of boost::python::object takes boost::python::object . It should store this bp::object in a known place (probably a member variable of the listener subclass).

Then pass another C ++ function to the setResponse base, which will know how to search and call the function in bp::object . If events are to be raised in another thread, you also need to ensure that Python Global Interpreter Lock is correctly handled as described here: does boost.python not support parallelism? .

+2
source

Source: https://habr.com/ru/post/909493/


All Articles