Добрый день всем! Недавно при прототипировании одной из частей разрабатываемого нами продукта возникла интересная задача: нам нужно было проверить склейку Python и C++.
Это было связано с тем, что основной код был написан в плюсах, и нужно было подключать внешнюю библиотеку Websockets, написанную на Python (соответствующей библиотеки на C++ на тот момент не было).
Схема взаимодействия для такой задачи достаточно проста.
Из C++ вызывается функция подключения к серверу (в python), ее адрес передается как параметр.
Соответственно, когда Python получает сообщение, он передает его обратно методу C++.
При написании кода мы использовали библиотеку Python Websocket от Autobahn ( 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 ), СВИГ( http://www.swig.org/ ), Py++, Pybindgen, Pyrex. В результате самым популярным решением был выбран Boost.Python. Во-первых, давайте напишем простой эхо-клиент на Python, который будет отправлять себе сообщение «Hello world» раз в секунду, получать его и отправлять на C++.
cppMethods будет объявлен в коде C++, cppMethods.printMessage(msg) — это как раз то место, где присоединяется Python, напрямую вызывая функцию C++, которая будет печатать полученное сообщение.
Вот код Python — echo-client.py :
Теперь давайте напишем код на C++, в котором опишем нашу функцию, вызываемую из Python. Чтобы использовать Python C-API, вам необходимо включить Python.h. Обратите внимание, что на данном этапе мы еще не используем Boost.Python , только на самом деле родной Python C-API .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()
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}
};
В последнем объявлении мы описали, что при вызове функции printMessage метод C++ будет вызываться из Python печатьстрока .
Что ж, давайте, наконец, свяжем все это воедино.
Для проверки работы вебсокетов помимо эхо-клиента использовалась ссылка на html5labs. 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, а именно функцией вызов_метода , иначе нам пришлось бы писать значительно больше кода.
Ну вот как то так.
Здесь мы инициализировали Методы вставки для Python, вызывая их cppMethods а затем вызвал метод из Python Соединять и передал ему строку «адрес».
В результате наше приложение печатает строку «Hello World» (которую Python отправляет самому себе) раз в секунду, а также любое сообщение, поступающее от сервера веб-сокетов.
Вот как вы можете связать Python и C++.
Буду благодарен за комментарии по теме.
Обновление.
Исправил код в соответствии с замечаниями из комментариев.
Теги: #python #c plus plus #websockets #boost #python #C++
-
Узловое Программирование
19 Oct, 24 -
Резервное Копирование: Google Case
19 Oct, 24 -
Домашняя Серверная Версия Ubuntu
19 Oct, 24 -
Openstack Нуждается В Более Чем Одной Шляпе
19 Oct, 24