callback vers un fonction membre, sans parametre "user"

callback vers un fonction membre, sans parametre "user" - C++ - Programmation

Marsh Posté le 21-01-2007 à 20:17:53    

Salut,  
j'ai une API qui a besoin d'appeler un callback. Cette fonction de callback ne prend pas de parametre utilisateur, et vu que tout est encapsule dans un objet, j'ai beaucoup de mal a appeler la fonction membre sur le bon objet.  
 
Si il n'y a qu'une instance de l'objet, pas de probleme, je passe par une variable statique.  
 

Code :
  1. void fonction_callback( /* pas de parametre */ )
  2. {
  3.    MaClasse::pThis->vrai_callback();
  4. }
  5. class MaClasse
  6. {
  7.    static MaClasse* pThis;
  8.    void Init()
  9.    {
  10.       pThis = this;
  11.       api->register_callback(fonction_callback);
  12.    }
  13.    void vrai_callback()
  14.    {
  15.  
  16.    }
  17. }


 
Mais comment etendre ca pour N instances de MaClasse ?
 
edit :  
 
j'ai tente une approche par generation de code : au moment ou je fais register_callback, je cree une zone qui va contenir un truc du genre :
 
mov ecx, 0x0011A3B0
call vrai_callback
 
mais je galere avec les conventions d'appel, parce que Visual C++ ne me laisse pas prendre l'adresse de "vrai_callback"
 
edit2: comme vous l'aurez compris je travaille sous Windows et je n'ai rien contre une solution "pas portable" dans la mesure ou cette foutue API ne l'est pas.


Message édité par Ace17 le 22-01-2007 à 12:01:10
Reply

Marsh Posté le 21-01-2007 à 20:17:53   

Reply

Marsh Posté le 22-01-2007 à 10:56:36    

Bon, j'ai clarifie le probleme, donc up :hello:

Reply

Marsh Posté le 22-01-2007 à 19:39:18    

Je ne suis pas trop C++ donc désolé si ma réponse n'est pas juste : j'utiliserais un vecteur de MaClasse plutôt qu'un objet statique.

Reply

Marsh Posté le 22-01-2007 à 19:44:00    

Mais alors, une fois que tu es dans "fonction_callback", tu choisis quelle case du vecteur ?

Reply

Marsh Posté le 22-01-2007 à 19:49:23    

Il faudra que tu gères la synchro entre chaque carte son en utilisant les event par exemple : tu signaleras le thread qui aura fini à l'autre thread qui travaille encore de la même manière qu'un WorkerThread.

Reply

Marsh Posté le 22-01-2007 à 19:59:05    

Attends, il n'y a qu'un seul thread dans la pratique.
edit : ou du moins, ca pourrait etre le cas, le probleme serait le meme


Message édité par Ace17 le 22-01-2007 à 19:59:24
Reply

Marsh Posté le 22-01-2007 à 20:17:49    

Justement, je pense que tu pourrais attribuer un thread pour chaque carte d'où les workerThread, non ?
C'est pas pire que le dual core, la, chaque spu = un core  :??:  
'Fin c'est une première approche.

Reply

Marsh Posté le 22-01-2007 à 21:19:40    

Je ne vois pas comment tu veux faire. Dans la pratique, l'API en question, c'est une instance de driver ASIO. Chaque objet n'inscrit pas un, mais quatre callbacks (bufferSwitch, bufferSwitchTimeInfo, sampleRateDidChange, et asioMessage) destinés a etre appelés par l'instance de driver.
 
Ma classe est nommée AudioManager. Dans la pratique, c'est un objet qui permet de spécifier un format, un nom de fichier, un nom de driver ASIO, et un top de départ.  
 
J'ai donc deux AudioManager, dont chacun inscrit 4 callbacks, et évidemment chaque AudioManager le fait aupres de sa propre instance de driver ASIO.
 
Evidemment, il n'y a pas de logique dans l'ordre d'appel des callbacks entre les deux drivers, c'est a dire que les deux sont indépendants.
 
Ce que tu proposes (a savoir, si j'ai bien compris, rediriger tous les callbacks vers un objet central et faire pomper les AudioManager dedans) pourrait marcher si il y avait un moyen, une fois dans le callback, de savoir lequel des deux drivers a provoqué l'appel.  
 

Reply

Marsh Posté le 22-01-2007 à 21:26:30    

Mais oublions le son et l'ASIO, le probleme n'est pas lié a ca. Voici un exemple plus général de mon probleme.
 

Code :
  1. /*
  2. * cette classe est figée, elle fait partie de l'API.
  3. */
  4. class objet_qui_appelle_un_callback
  5. {
  6. public:
  7.    void* m_Function;
  8.    void register_callback(void (*function)())
  9.    {
  10.       m_Function = function;
  11.    }
  12.    void OnEvent()
  13.    {
  14.       m_Function();
  15.    }
  16. };
  17. /*
  18. * cette classe, c'est la mienne, donc modifiable a souhait
  19. */
  20. class objet_qui_utilise_celui_qui_appelle_un_callback
  21. {
  22.    public:
  23.       objet_qui_appelle_un_callback m_ObjetQuiAppelleUnCallback;
  24.      
  25.       objet_qui_utilise_celui_qui_appelle_un_callback()
  26.       {
  27.          m_ObjectQuiAppelleUnCallback.register_callback(Callback);
  28.       }
  29.       void Callback()
  30.       {
  31.       }
  32. };
  33. objet_qui_utilise_celui_qui_appelle_un_callback Objet1, Objet2;


 
Voila, j'espere que c'est plus clair comme ca. Evidemment ca ne compile pas car la ligne  

Code :
  1. m_ObjectQuiAppelleUnCallback.register_callback(Callback);


est complètement fausse. Dans la mesure ou Callback n'a pas la bonne convention d'appel. Mais elle montre ce que je veux faire.


Message édité par Ace17 le 22-01-2007 à 21:27:29
Reply

Marsh Posté le 22-01-2007 à 23:42:01    

Ah ok, c'est plus un problème de C++ alors, j'avais utilisé ceci (les templates) pour avoir le support des callbacks en C++.

Reply

Marsh Posté le 22-01-2007 à 23:42:01   

Reply

Marsh Posté le 23-01-2007 à 09:49:37    

Oui mais moi la forme du callback m'est imposee.
 
J'ai trouve la solution, que le regrette chrisbk avait trouve avant moi. Il s'agit de la technique "colgate".
http://forum.hardware.fr/hfr/Progr [...] 0082_1.htm

Reply

Marsh Posté le 23-01-2007 à 11:35:56    

Je ne savais pas ceci (le param this en param) d'où surement mon incompréhension  :whistle:  
Ravis que tu ais trouvé la solution :)

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed