Comme Igor Oks indicates, vous ne pouvez pas faire cela. Le reste de cette question n'est pas tellement une réponse à votre problème, mais une discussion sur la façon dont quelque chose comme ceci devrait fonctionner avec une API de rappel correctement conçue (il semble que celle que vous utilisez ne l'est pas).
La plupart des interfaces de rappel bien conçues vous permettent de fournir un "void *
" ou un autre moyen d'obtenir un contexte dans le rappel. Une manière courante d'utiliser ceci avec C++ est de passer un pointeur d'objet dans le paramètre de contexte void *
, puis la fonction de rappel peut le renvoyer dans un pointeur d'objet et appeler la méthode membre pour effectuer le travail réel. C'est dommage que l'API de rappel que vous utilisez ne fournisse pas de données de contexte.
Strictement parlant, le rappel doit être extern "C"
, mais l'utilisation de méthodes membres statiques pour les rappels est courante et je pense que dans la pratique il n'y a jamais de problème. (Cela suppose que l'API de rappel est une interface C, qui est de loin la plus courante).
Un exemple:
// callback API declaration's
extern "C" {
typedef unsigned int callback_handle_t;
typedef void (*callback_fcn_t)(void* context, int data1, int data2);
callback_handle_t RegisterCallback(callback_fcn_t, void* context);
void UnregisterCallback(callback_handle_t);
}
// ----------------------------------
// prototype for wrapper function that will receive the callback and
// transform it into a method call
extern "C"
static void doWorkWrapper(void* context, int data1, int data2);
// the class that does the real work
class worker {
public:
worker() {
hCallback = RegisterCallback(doWorkWrapper, this);
}
~worker() {
UnregisterCallback(hCallback);
}
void doWork(int data1, int data2) {
// ...
};
private:
callback_handle_t hCallback;
};
// the wrapper that transforms the callback into a method call
extern "C"
static void doWorkWrapper(void* context, int data1, int data2)
{
worker* pWorker = static_cast<worker*>(context);
pWorker->doWork(data1, data2);
}
Rien n'est impossible en C.Votre problème m'a intrigué, j'ai donc écrit un blogspot sur une façon hackish de le résoudre: http://nothingintoinsight.blogspot.com/2009/02/how-to-hack-closures-in-your-c-code-ou. html – user51568