Я пишу программу на python, которая должна иметь возможность передавать «вызываемые», которые зарегистрированы в классе C ++.
До сих пор я написал следующий код:
C ++:
class MyClass
{
...
public:
register_callback(boost::function<void (int)> fun);
};
Python / C API:
class_<MyClass, boost::shared_ptr<MyClass>, boost::noncopyable>("MyClass", no_init)
.def("register_callback", &MyClass::register_callback);
Код компилируется, но когда я вызываю метод из python, передавая вызываемый (в моем случае, другой метод экземпляра), я получаю следующую ошибку времени выполнения:
Boost.Python.ArgumentError: Python argument types in
MyClass.register_callback(MyClass, instancemethod)
did not match C++ signature:
register_callback(MyClass {lvalue}, boost::function<void ()(int)>)
Я думаю, что мне нужен способ сказать, что boost может безопасно передавать вызываемый объект каждый раз, когда требуется boost :: function. Все работает, если я использую решение ручной работы:
void my_caller(MyClass* obj, object callable)
{
obj->register_callback(callable); // Works!
}
class_<MyClass, boost::shared_ptr<MyClass>, boost::noncopyable>("MyClass", no_init)
.def("register_callback", &my_caller);
Поскольку у меня есть только несколько таких функций регистрации, я мог бы придерживаться ручного решения (с помощью макросов, чтобы помочь),
но мне интересно, как я могу сказать, чтобы boost :: python сделал преобразование автоматически.
Глядя на документацию, я нашел директиву to_python_converter, которая, по иронии судьбы, делает в точности то, что мне нужно ...