6

そのため、C++ で記述され、Boost ライブラリを使用する単純なイベント ライブラリがあります。上記のライブラリを Python に公開したかったので、当然 Boost::Python に目を向けました。最終的にはコンパイルするコードを手に入れましたが、今ではかなりの問題に直面しています。私のライブラリは高次のプログラミング手法を使用しています。たとえば、ライブラリは、イベント クラス、イベント マネージャ クラス、およびイベント リスナ クラスの 3 つのメイン クラスで構成されています。イベント リスナ クラスが問題を引き起こします。コード:

    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++ から呼び出し可能なままにしたいので、オーバーロードまたはラッパーを使用する必要があります。

4

1 に答える 1

2

関数の代わりに asetResponseを取るラッパーが必要になります。boost::python::objectこれをbp::object既知の場所 (おそらくlistenerサブクラスのメンバー変数) に格納する必要があります。

次に、別の c++ 関数を basesetResponseに渡します。これは、 で関数を検索して呼び出す方法を認識しますbp::object。イベントが別のスレッドで呼び出される場合は、ここで説明されているように、Python のグローバル インタープリター ロックを適切に処理する必要もあります: boost.python は並列処理をサポートしていませんか? .

于 2012-02-28T15:30:38.500 に答える