2010-05-31 11 views
5

J'ai besoin d'écrire du code pour effectuer un traitement en temps réel qui est assez complexe en termes de calcul. Je voudrais créer des classes Python pour gérer tous mes scripts, et laisser les parties intensives de l'algorithme codées en C++ afin qu'elles puissent fonctionner aussi vite que possible. Je voudrais instancier les objets en Python, et avoir les algorithmes C++ dans le script avec des callbacks dans python. Quelque chose comme:Traitement et rappels en temps réel avec Python et C++

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

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

Sera-ce possible? Comment puis-je exécuter un callback dans python à partir d'une boucle qui s'exécute dans un module C++? Quelqu'un at-il un lien ou un tutoriel pour m'aider à le faire correctement?

Répondre

3

Je suggère d'utiliser Boost.Python comme suggéré par ChristopheD. Un gotcha serait si l'extension C++ s'exécute dans son propre contexte de thread (pas créé par Python). Si c'est le cas, assurez-vous d'utiliser les fonctions PyGILState_Ensure() and PyGILState_Release() lorsque vous appelez du code Python à partir de C++.

De la documentation (http://docs.python.org/c-api/init.html#thread-state-and-the-global-interpreter-lock):

partir de la version 2.3, les fils peuvent désormais profiter de la PyGILState _ *() pour faire tout ce qui précède automatiquement. L'idiome typique pour appeler en Python à partir d'un fil C est maintenant:

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) 

Je recommande de faire les callbacks court & doux - de limiter la nécessité d'effectuer la gestion des exceptions dans le code C++. Si vous utilisez wxPython, vous pouvez utiliser son robuste système d'événement asynchrone. Ou les rappels peuvent mettre des événements sur une file d'attente et vous pouvez avoir un thread dédié à l'exécution asynchrone du code de rappel/événement.

Même avec la magie Boost.Python, vous devez vous familiariser avec cette partie de l'API Python C lorsque vous traitez des threads. (N'oubliez pas d'envelopper les fonctions C++ avec Py_BEGIN_ALLOW_THREADS et Py_END_ALLOW_THREADS pour libérer le GIL!)

0

Here est un exemple de comment faire des rappels python en utilisant Cython. Il pourrait être utile de regarder Pyrex ainsi. Les deux peuvent rendre l'intégration de C/C++ avec Python plutôt facile.

0

Nous faisons ce que vous faites beaucoup au travail. Nous aimons Python mais ce n'est pas assez rapide parfois.
Boost et Swig sont tous deux bons pour le faire. Vous devriez également consulter ce lien sur Python Performance ils parlent un peu de NumPy qui peut vous aider.