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
PtrFct_t est un pointeur sur fonction membre de classeCLangage.cpp:326: avertissement : converting from 'PtrFct_t {aka void (CLangage::*)()}' to 'void*' [-Wpmf-conversions]
Register(static_exec_callback, this, (void *)fct);
^
2eme problème lors du rappel dans la fonction static libre
Code : Sélectionner tout - Visualiser dans une fenêtre à part typedef void (CLangage:: * PtrFct_t)(void);
Je prends un message d'erreur
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)(); }
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)CLangage.cpp:332: erreur : invalid cast from type 'void*' to type 'PtrFct_t {aka void (CLangage::*)()}'
PtrFct_t fct = (PtrFct_t)MemberFct;
^
Partager