Bonjour à tous,
Je vais essayer d'expliquer clairement mon problème. J'ai une classe de base Tool qui représente un outil sélectionné par l'utilisateur que je dérive en une classe ConcreteTool pour mon exemple. De la même façon, j'ai une classe Event (événement utilisateur) dérivée en MouseDownEvt par exemple auquel mon ConcreteTool réagit. L'idée c'est que chaque événement connait la fonction membre de ConcreteTool à appeller. Chaque Event possède donc un pointeur vers une fonction membre virtuelle de Tool. Voici l'allure de mes classes :
Tool.h
Event.h
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 class Tool { public: Tool(void); ~Tool(void); virtual void onLeftMouseDown(void* sender, EventArg* e) {} virtual void onLeftMouseUp(void* sender, EventArg* e) {} virtual void onLeftMouseDrag(void* sender, EventArg *e) {} ... }; class ConcreteTool { public: virtual void onLeftMouseDown(void* sender, EventArg* e) { std::cout<<test<<std::endl; } ... };
Pour créer un événement, je m'y prend comme cela :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 class EventArg; class Tool; typedef void (Tool::*toolFnPtr)(void*, EventArg*); class Event { protected : void* sender; EventArg* arg; toolFnPtr callback; public: Event(void); ~Event(void); inline void* getSender() const { return sender ; } inline toolFnPtr getCallback() const { return callback; } inline virtual EventArg* getArguments() { return arg; } };
Enfin, un gestionnaire traite l'événement ainsi :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 MouseDownEvt::MouseDownEvt(void *evtSender, const Vect2 &p, ModifierKey key) : Event() { sender = evtSender; arg = new MouseDownEvtArg(p, key); callback = &Tool::onLeftMouseDown; }
Je compile avec le compilo de vs2005 et comme raison du crash, j'ai droit à un "Acces violation". En observant les adresses avec le débuggueur, j'ai remarque qu'il y avait des différences.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 void ToolSystem::treatEvent(Event *evt) { void* sender = evt->getSender(); EventArg* arg = evt->getArguments(); toolFnPtr fun = evt->getCallback(); (currentTool->*fun)(sender, arg); // CRASH ... }
Variable:---------------------Value:-----------------Type
&Tool::onLeftMouseDown-----0x00411b90"U‹ììÌ"-------char *
fun--------------------------0x00356818 ------------void (void *, EventArg *)*
&IdleTool::onLeftMouseDown -0x00411a30"U‹ìjÿh+qA"--char *
Ces adresses sont aussi différentes des adresses de la vtable de currentTool.
Quelqu'un peut-il me dire où ça cloche et comment y remédier ? J'espère avoir été assez clair.
Merci d'avance.
Partager