Bonjour,

Je suis entrain de réaliser un parser de langage et j'ai un problème que je n'arrive pas à résoudre de manière élégante ou sans warning.

La définition du langage est dans une classe à part (appelons la CLangage).
Le parser est aussi dans une classe à part (appelons la CParser).

Les 2 classes (CLangage et CParser) sont indépendante l'une de l'autre (aucun héritage commun).

CLangage "enregistre" dans CParser les fonctions que le Parser doit appeler lorsque les éléments de langages sont rencontrés.

C'est à dire en pseudo code:
Code Pseudocode CLangage : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
CLangage::Register()
{
   CParser::Register(this, Callback);
}
 
CLangage::Callback()
{
   // fonction qui doit etre appelée par le parser
   ...
}
Code Pseudocode CParser : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
 
CParser::Register(This, Callback)
{
   // enregistrement des parametres dans m_this et m_callback
   ...
}
 
CParser::Execute()
{
   ...
   m_this->m_callback();
   ...
}

Voilà, dans l'idée, c'est assez simple mais je n'arrive pas à l'implémenter

Comme CParser ne connait pas CLangage, les pointeurs this et callback sont enregistrés comme des void * (aie) et je passe par une fonction statique libre de la classe CLangage pour reconstruire mes pointeurs (2eme aie)

Code Pseudocode CLangage : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
CLangage::Register()
{
   CParser::Register(static_libre, this, Callback);
}
 
void static_libre(This, Callback)
{
   This->Callback();
}
 
CLangage::Callback()
{
   // fonction qui doit etre appelée par le parser
   ...
}
Code Pseudocode CParser : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
 
CParser::Register(StaticLibre, This, Callback)
{
   // enregistrement des parametres dans m_static_libre, m_this et m_callback
   ...
}
 
CParser::Execute()
{
   ...
   m_static_libre(m_this, m_callback);
   ...
}

Question : est ce que cela parait assez élégant comme solution ou bien est ce que vous penseriez à une autre manière plus élégante et/ou simple pour le faire

1er problème dans la fonction CLangage::Register(), j'ai du mal a transformer le pointeur de fonction membre que je reçoit en void *. Je recois un warning que je n'arrive pas à comprendre
CLangage.cpp:326: avertissement : converting from 'PtrFct_t {aka void (CLangage::*)()}' to 'void*' [-Wpmf-conversions]
Register(static_exec_callback, this, (void *)fct);
^
PtrFct_t est un pointeur sur fonction membre de classe
Code : Sélectionner tout - Visualiser dans une fenêtre à part
typedef void (CLangage:: * PtrFct_t)(void);
2eme problème lors du rappel dans la fonction static libre
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
void CLangage::StaticLibre(void * This, void * MemberFct)
{
	CLangage * this_ptr = (CLangage *)This;
	PtrFct_t fct = (PtrFct_t)MemberFct;
	(this_ptr->*fct)();
}
Je prends un message d'erreur
CLangage.cpp:332: erreur : invalid cast from type 'void*' to type 'PtrFct_t {aka void (CLangage::*)()}'
PtrFct_t fct = (PtrFct_t)MemberFct;
^
Merci de votre aide (et oui, je suis toujours vivant mais je suis nettement moins actif sur le forum car j'ai énormément de travail)