Обработка в реальном времени и обратные вызовы с Python и C ++ - PullRequest
6 голосов
/ 01 июня 2010

Мне нужно написать код для выполнения некоторой обработки в реальном времени, которая довольно сложна в вычислительном отношении. Я хотел бы создать несколько классов Python для управления всеми моими сценариями и оставить интенсивные части алгоритма написанными на C ++, чтобы они могли работать максимально быстро. Я хотел бы создать экземпляры объектов в Python и заставить алгоритмы C ++ вернуться в сценарий с обратными вызовами в Python. Что-то вроде:

myObject = MyObject()
myObject.setCallback(myCallback)
myObject.run()

def myCallback(val):
    """Do something with the value passed back to the python script."""
    pass

Это будет возможно? Как я могу запустить обратный вызов в Python из цикла, который выполняется в модуле C ++? У кого-нибудь есть ссылка или учебное пособие, чтобы помочь мне сделать это правильно?

Ответы [ 4 ]

4 голосов
/ 01 июня 2010

Взгляните на Boost.Python . Его учебник начинается здесь .

3 голосов
/ 01 июня 2010

Я предлагаю использовать Boost.Python, как предложено ChristopheD. Добрался бы, если расширение C ++ работает в своем собственном контексте потока (не создан Python). Если это так, обязательно используйте функции PyGILState_Ensure() и PyGILState_Release() при вызове кода Python из C ++.

Из документов (http://docs.python.org/c-api/init.html#thread-state-and-the-global-interpreter-lock):

Начиная с версии 2.3, темы Теперь можно воспользоваться PyGILState _ * () выполняет все функции выше автоматически. Типичный идиома для вызова в Python из C Тема сейчас:

PyGILState_STATE gstate;
gstate = PyGILState_Ensure();

/* Perform Python actions here.  */
result = CallSomeFunction();
/* evaluate result */

/* Release the thread. No Python API allowed beyond this point. */
PyGILState_Release(gstate)

Я рекомендую сделать обратные вызовы короткими и приятными - чтобы ограничить необходимость выполнения обработки исключений в коде C ++. Если вы используете wxPython, вы можете использовать его надежную систему асинхронных событий. Или обратные вызовы могут помещать события в очередь, и у вас может быть поток, предназначенный для асинхронного выполнения кода обратного вызова / события.

Даже с магией Boost.Python вам придется знакомиться с этой частью Python C API при работе с потоками. (Не забудьте обернуть функции C ++ Py_BEGIN_ALLOW_THREADS и Py_END_ALLOW_THREADS, чтобы освободить GIL!)

0 голосов
/ 01 июня 2010

Мы делаем то, что вы делаете много на работе. Нам нравится python, но иногда он бывает недостаточно быстрым.
Boost и Swig оба хороши для этого. Вы также должны проверить эту ссылку на Python Производительность , они немного говорят о NumPy , который может помочь вам.

0 голосов
/ 01 июня 2010

Здесь - пример того, как сделать обратные вызовы Python, используя Cython . Возможно, стоит взглянуть и на Pyrex . И то, и другое может сделать интеграцию C / C ++ с Python довольно простой.

...