2009-02-04 5 views
4

Je développe un programme qui utilise DirectShow pour récupérer des données audio à partir de fichiers multimédias. DirectShow utiliser thread pour transmettre des données audio à la fonction de rappel dans mon programme, et je laisse cette fonction de rappel appeler une autre fonction en Python.Comment appeler une fonction python à partir d'un thread de langue étrangère (C++)

J'utilise Boost.Python pour wrapper ma bibliothèque, la fonction de rappel:

class PythonCallback { 
private: 
    object m_Function; 
public: 
    PythonCallback(object obj) 
     : m_Function(obj) 
    {} 

    void operator() (double time, const AudioData &data) { 
     // Call the callback function in python 
     m_Function(time, data); 
    } 

}; 

vient ici le problème, un fil de DirectShow appelle mon PythonCallback, à savoir, appelez la fonction en Python. Une fois qu'il appelle, mon programme tombe en panne. J'ai trouvé que cela devrait poser problème. Ensuite, je trouvé ce document:

http://docs.python.org/c-api/init.html

Il semble que mon programme ne peut pas appeler à la fonction Python de fil directement, parce qu'il est global interprète Lock. Le GIL du python est si complexe, je n'ai aucune idée de comment cela fonctionne. Je suis désolé, ce que je peux faire est de demander. Ma question est. Que dois-je faire avant et après avoir appelé une fonction Python à partir de threads?

Cela peut ressembler à ceci.

void operator() (double time, const AudioData &data) { 
    // acquire lock 
    m_Function(time, data); 
    // release lock 
} 

Merci. Victor Lin.

Répondre

6

Jetez un oeil à PyGILState_Ensure()/PyGILState_Release(), du PEP 311 http://www.python.org/dev/peps/pep-0311/

Voici un exemple tiré du PEP lui-même:

void SomeCFunction(void) 
{ 
    /* ensure we hold the lock */ 
    PyGILState_STATE state = PyGILState_Ensure(); 
    /* Use the Python API */ 
    ... 
    /* Restore the state of Python */ 
    PyGILState_Release(state); 
} 
+0

Plus de documentation: http://docs.python.org/c-api/init.html#threads –

1

Que le rappel C++ place les données dans une file d'attente. Demandez au code python d'interroger la file d'attente pour extraire les données.

+0

Merci de votre réponse. Cela pourrait être une solution. Mais cependant, cette solution nécessite une opération de copie supplémentaire pour le tampon audio. Cela pourrait être un problème de performance. –

+0

Il peut être possible d'allouer de la mémoire en python, puis de passer le pointeur à votre code C++ pour qu'il puisse y déposer les données directement. –

Questions connexes