PythonとC ++の統合

すべての人に良い一日を!



最近、開発中の製品の一部のプロトタイプを作成するときに、1つの興味深い問題が発生しました。PythonとC ++の接着を確認する必要がありました。 これは、メインコードがプロで記述されているためであり、Pythonで記述された外部Websocketライブラリを接続する必要がありました(その時点では、対応するC ++ライブラリはありませんでした)。 このタスクの相互作用スキームは非常に単純です。 サーバーに接続する機能(Python)はC ++から呼び出され、そのアドレスはパラメーターとして渡されます。 したがって、メッセージを受信すると、PythonはそのメッセージをC ++メソッドに返します。



コードを記述する際には、AutobahnのWebsocket Pythonライブラリ( http://www.tavendo.de/autobahn/clientlibraries.html )が使用されました。これはC ++から呼び出す必要がありました。 これらの目的のために、PythonはPython C-API( http://docs.python.org/extending/index.html )を提供しますが、関数の呼び出しなどの多くの単純なアクションはいくつかのアクションによって実行されます。 少しグーグルで調べた後、そのようなアクションを簡素化する多くのライブラリが見つかりました:Boost.Python( http://www.boost.org/doc/libs/1_39_0/libs/python/doc/index.html )、SWIG( http:// www.swig.org/)、Py ++、Pybindgen、Pyrex ...その結果、Boost.Pythonが最も人気のあるソリューションとして選ばれました。



まず、Pythonで簡単なエコークライアントを作成します。このクライアントは、「Hello world」メッセージを1秒に1回送信し、受信してC ++で送信します。 cppMethodsはC ++コードで宣言されます。cppMethods.printMessage(msg)はPython側から接着する場所であり、受信したメッセージを出力するC ++関数を直接呼び出します。



Pythonコード-echo-client.pyは次のとおりです。

from twisted.internet import reactor from autobahn.websocket import WebSocketClientFactory, WebSocketClientProtocol, connectWS import cppMethods class EchoClientProtocol(WebSocketClientProtocol): def sendHello(self): self.sendMessage("Hello, world!") def onOpen(self): self.sendHello() def onMessage(self, msg, binary): cppMethods.printMessage(msg) reactor.callLater(1, self.sendHello) def Connect(addressStr): factory = WebSocketClientFactory(addressStr) factory.protocol = EchoClientProtocol connectWS(factory) reactor.run()
      
      







次に、Pythonから呼び出される関数を記述するC ++コードを記述します。 Python C-APIを使用するには、Python.hを含める必要があります。 この時点では、 Boost.Pythonをまだ使用しておらず、ネイティブPython C-API自体を使用していることに注意してください。



PrintEmb.cpp

 #include <Python.h> #include <iostream> #include <string> static PyObject * printString(PyObject * self, PyObject* args) { const char * toPrint; if(!PyArg_ParseTuple(args, "s", &toPrint)) { return NULL; } std::cout << toPrint << std::endl; Py_RETURN_NONE; } static PyMethodDef EmbMethods[] = { {"printMessage", printString, METH_VARARGS, "Return the string recieved from websocket server"}, {NULL, NULL, 0, NULL} };
      
      







前回の発表では、PythonからprintMessage関数を呼び出すと、C ++のprintStringメソッドが呼び出されることを説明しました。



そして最後に、すべてをまとめます。 エコークライアントに加えて、html5labsへのリンクを使用して、websocketの動作をテストしました。



WebSocketConnect.cpp

 #include <Python.h> #include <boost/python.hpp> #include <iostream> #include <string> #include "PrintEmb.cpp" void WebSocketConnect() { using namespace boost::python; Py_Initialize(); Py_InitModule("cppMethods", EmbMethods); PyObject * ws = PyImport_ImportModule("echo_client"); std::string address = "ws://html5labs-interop.cloudapp.net:4502/chat"; call_method<void>(ws, "Connect", address); Py_Finalize(); }
      
      





それでも、この場所では、Boostの機能、つまりcall_method関数を利用しました。そうしないと、大幅に多くのコードを記述する必要があります。



まあ、そのようなもの。 ここでは、PythonのEmbMethodsを初期化してcppMethodsを呼び出し、PythonからConnectメソッドを呼び出して、文字列「address」を渡しました。 その結果、アプリケーションは「Hello World」という行(Pythonが自分自身を送信する)を1秒に1回だけでなく、websocketサーバーからのメッセージも出力します。



これにより、PythonとC ++を接続できます。 このトピックに関するコメントに感謝します。



更新しました。 コメントからのコメントに従ってコードを修正しました。



All Articles