0

私は、C++クラスに登録されている「呼び出し可能オブジェクト」を渡すことができるはずのPythonでプログラムを書いています。これまでのところ、次のコードを記述しました。

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 :: 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ディレクティブが見つかりました。これは、皮肉なことに、必要なものとは正反対です...

4

1 に答える 1

1

あなたが推測したように、 MyClassはboost::python::objectしばらくの間渡されています。幸いなことに、解決策は十分に単純です-私は思います。コードは次のようになります(テストされていません)(http://mail.python.org/pipermail/cplusplus-sig/2010-February/015199.htmlから採用):register_callbackboost::function

...
struct callable_wrapper_t
{
    callable_wrapper_t( boost::python::object callable ) : _callable( callable ) {}

    void operator()()
    {
        // These GIL calls make it thread safe, may or may not be needed depending on your use case
        PyGILState_STATE gstate = PyGILState_Ensure();
        _callable();
        PyGILState_Release( gstate );
    }

    boost::python::object _callable;
};
...
class MyClass
{
...
public:
    register_callback(boost::function<void (int)>(callback_wrapper_t(fun)));
};
...
class_<MyClass, boost::shared_ptr<MyClass>, boost::noncopyable>("MyClass", no_init)
    .def("register_callback", &my_caller);
...

また、py_boost_function.hppを確認することをお勧めします

于 2010-09-11T08:00:30.877 に答える