Problème de retour de dll sous l’API32
Pour les spécialistes du multiprocessing:
Bonjour,
J’ai un .exe (une fenêtre) qui tourne donc avec quelque part une boucle :
Code:
1 2 3 4 5
| while( GetMessage( &message, NULL, 0, 0))
{
TranslateMessage( &message );
DispatchMessage( &message );
} |
et qui récupère quelque part dans une CALLBACK les messages WM_COMMAND.
Parmi mes messages WM_COMMAND, j’ai en particulier les deux suivants :
1.- un message (case message1 ) qui exécute une fonction 1 dans une DLL,
je passe sur le détail du chargement de la DLL, retenons simplement qu’après son chargement j’ai simplement :
suivi du break habituel
2.- un autre message (case message2) qui exécute une fonction 2 dans la même DLL,
j’ai donc sous un autre (case message2) l’appel de la fonction 2 :
toujours suivi du break habituel
voilà pour ma fenêtre en .exe
Pour ce qui concerne ma dll :
Ma fonction 1 exécute un HOOK et se met à boucler volontairement pour récupérer par sa propre CALLBACK les messages des évènements piégés sur une boucle du style :
Code:
1 2 3 4 5
| while( (GetMessage( &messdll, NULL, 0, 0))&&(runhook))
{
TranslateMessage( &messdll );
DispatchMessage( &messdll );
} |
avec runhook initialisé à true.
Ma fonction 2 ne fait elle aucune boucle, elle a pour but d’arrêter le HOOK lancé par la fonction 1 et de stopper la boucle de la fonction 1. Ma fonction 2 se contente donc simplement de faire le UnHook nécessaire puis de faire passer runhook à false ce qui on le voit permet de sortir de la boucle GetMessage de la fonction 1.
Comportement de l’ensemble :
Quand je lance la fonction 1 tout se passe comme voulu :
Le hook de la DLL s’exécute correctement et en parallèle je peux continuer à utiliser le .exe de ma fenêtre pour exécuter d’autres commandes (bien noter cependant que je ne suis toujours pas revenu sur le break qui suit l’appel à la fonction 1).
Quand je lance la fonction 2 le hook s’arrête comme prévu, je reviens bien sans problème sur le break qui suit l’appel de la fonction 2, mais en parallèle comme la fonction 1 sort de sa boucle interne je reviens aussi sur le break qui suit la fonction 1 et c’est là qu’il y a un problème : ceci tue mon .exe donc ma fenêtre ce qui n’était pas le but recherché !!
J’espère avoir été clair dans mes explications, ce problème est-il résoluble ?
Je suis conscient qu'il y a un problème de multiprocessing: je reviens dans mon programme principal (ma fenêtre en .exe) par deux endroits différents comme s'il y avait dorénavant deux exécutions en parallèle dans le même processus, ce qui n'est pas très satisfaisant pour l'esprit ! Comment donc conserver le déroulement de mon programme principal tout en tuant par le processus 2 (fonction 2) le processus 1 lancé par la fonction 1 ?
Merci
retour de dll suite et probablement fin
Bon en essayant la version proposée par nirgal76, j’ai trouvé le problème, le test de la version de nirgal76 m’a inquiété car même en enlevant la boucle de la fonction 1, le retour immédiat de la fonction 1 me tuait aussi ma fenêtre ! J’ai même enlevé le sethook de la fonction 1 qui ne faisait plus rien et qui à son retour me tuait quand même ma fenêtre !! alors que la fonction 2 ne me plantait pas la fenêtre. Je me suis donc dit que l’erreur devait être très grossière !
Le début de ma fonction 1 commençait ainsi :
Code:
extern "C" __declspec(dllexport) DWORD WINAPI SetHook(LPVOID lpParameter){}
Le début de ma fonction 2 commençait ainsi ::
Code:
extern "C" __declspec(dllexport) DWORD WINAPI StopHook(){}
J’ai simplement modifié le début de la fonction 1 ainsi :
Code:
extern "C" __declspec(dllexport) DWORD WINAPI SetHook(){}
Je pensais que le LPVOID lpParameter que j’avais recopié depuis un exemple était tout simplement inutile puisque pas utilisé et qu’il n’empêchait pas la fonction 1 de fonctionner correctement, par contre il s’avère que c’est lui qui me faisait planter ma fenêtre au retour de la fonction 1. Après donc un premier nouveau test ma dll (avec boucle interne) fonctionne correctement et ne me plante plus ma fenêtre à son retour. Pour l’instant je n’ai pas retesté la version simplifiée (sans boucle interne) de nirgal76, a priori, je ne vois pas pourquoi elle ne marcherait pas en liaison avec mon programme principal. Toutefois, il doit y avoir une restriction à mon sens avec cette version simplifiée, il faut que je vérifie, mais ma version avec boucle interne offre l’avantage que je peux lancer ma dll indépendamment de mon programme principal par un simple : rundll32 mydll.dll,SetHook. Pour la version simplifiée (sans boucle interne) ça me paraît, a priori, compromis.
Je vous remercie et je suis navré d’avoir pris autant de votre temps.
Cordialement,