IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Threads & Processus C++ Discussion :

Problème de retour de dll sous l’API32


Sujet :

Threads & Processus C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    214
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 214
    Par défaut 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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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

  2. #2
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Bonjour,
    Qu'entends-tu par faire un hook/unhook ? Peux-tu montrer cette partie de code ?

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    214
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 214
    Par défaut Retour DLL (suite)
    Dans mon programme principal (ma fenêtre en .exe) j’ai quelque part après la boucle TranslateMessage, DispatchMessage de GetMessage:
    (pour simplifier j’ai enlevé un peu partout quelques tests de vraisemblance qui n’apportaient rien à la compréhension)

    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
    LRESULT CALLBACK analysemessage( HWND clefenetre, UINT IDMsg, WPARAM wParam, LPARAM lParam ) 
    { 
        switch(IDMsg)
        { 
            case WM_COMMAND:
    	switch(LOWORD(wParam))
    	{
    	      case Ext_STARTDLL :
    		hinstdll = LoadLibrary(chemindll);
    		dllEntryAdd1 = GetProcAddress(hinstdll, dllEntrySet); // dllEntrySet = “SetHook”
    		dllEntryAdd1(); // lancement de la fonction 1
    		break;
    	       case Ext_STOPDLL :
    		dllEntryAdd2 = GetProcAddress(hinstdll, dllEntryStop); // dllEntryStop = “StopHook”
    		dllEntryAdd2(); // lancement de la fonction 2
    		break;
    //Ci-dessous la fonction 1 de ma dll :
    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
    extern "C" __declspec(dllexport) DWORD WINAPI SetHook(LPVOID lpParameter)
    {
        if(!n0instDLL) return 0;
        clehook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)analyseevent, n0instDLL, NULL);
        if(clehook==NULL) 
        {
    	return 0;
        } else
        {
    	while( (GetMessage( &messdll, NULL, 0, 0))&&(runhook)) // runhook initialisé à true
    	{
    		TranslateMessage( &messdll ); 
    		DispatchMessage( &messdll ); 
    	}
    	return 1;
        }
    }
    //Ci-dessous la fonction 2 de ma dll :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    extern "C" __declspec(dllexport) BOOL WINAPI StopHook()
    {
    	runhook=false;
    	if(UnhookWindowsHookEx(clehook))
    	{	
    		return true;
    	} else
    	{
    		return false;
    	}
    }
    //Ci-dessous le point d’entrée de ma dll :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD dwReason, LPVOID lpReserved)
    {
    	n0instDLL=hInst; // récupération de l’instance de ma dll
    	return TRUE;
    }
    Je répète enfin que ma fonction 1 marche parfaitement et ma fonction 2 aussi, j’ai par ailleurs dans le programme principal des tests que je n’ai pas mis ici qui me permettent de vérifier que je reviens bien sur les break qui suivent les appels aux fonctions 1 et 2. En fait c'est l'arrêt de la fonction 1 qui provoque l'arrêt de mon .exe. Car si par exemple dans la fonction 2 je me contente de faire le unhook sans mettre le runhook à false, le hook s'arrête correctement, mon .exe continue à fonctionner correctement par contre ce qui me gêne c'est que ma fonction 1 continue à boucler sans ne plus traiter aucun évènement, il me paraissait donc plus logique de sortir de cette boucle infinie.

  4. #4
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par Athur Voir le message
    par contre ce qui me gêne c'est que ma fonction 1 continue à boucler sans ne plus traiter aucun évènement.
    en es-tu sur ?

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    214
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 214
    Par défaut Retour dll (suite)
    Ca me paraît évident, il n'y a qu'à regarder la boucle de la fonction1 de ma dll:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    while( (GetMessage( &messdll, NULL, 0, 0))&&(runhook))
    		{
    			TranslateMessage( &messdll ); 
    			DispatchMessage( &messdll ); 
    		}
    			return 1;
    Comme je l'ai dit dans mes messages précédents quand je me contente de faire le unhook avec la fonction 2 sans modifier runhook qui reste donc à true, la fonction 1 arrête de piéger les touches du clavier (c'est ce que je veux) mais elle ne sort pas de la boucle ci-dessus, sinon la fonction 1 se terminerait et je le saurais car j'arriverais sur le break qui suit l'appel à la fonction 1 dans le programme principal appelant (je ne l'ai pas mis dans le code listé précédemment pour ne pas surcharger, mais dans mon programme principal je trace le retour de la fonction 1 par un message explicite juste avant le break!).
    Par contre lorsque dans ma fonction 2 en plus du unhook, je fais passer runhook à false, la fonction 1 se termine ce qui est logique et j'ai bien dans mon programme principal la trace du retour de la fonction 1 puisque j'ai le temps de sortir le message avant que ma fenêtre du programme principal ne disparaisse.
    Enfin, comme je l'ai suggéré à la fin de mon 1er message, il me paraît peu plausible que le problème puisse venir d'un mauvais fonctionnement de la fonction 1 ou 2. Mais par contre, je ne sais pas si ça a été bien saisi, il y a dans cette façon de faire un problème très dérangeant au plan logique et je pencherais plutôt dans cette direction et c'est surtout sur ce point qu'un avis m'intéresse. Comment réexpliquer:
    Dans mon programme principal (qui est une fenêtre) j'analyse les messages windows consécutifs à un choix dans le menu de la fenêtre par quelque part un suivi de multiples séquences: case/traitement de la commande/break puis fin du switch.
    un des traitements de la commande est le lancement de la fonction 1, un autre est le lancement de la fonction 2. Ce qu'il faut bien voir c'est que la fonction 1 est particulière: elle part en boucle jusqu'à ce que je passe une autre commande du menu pour l'arrêter, donc la fonction 1 ne revient pas dans un premier temps sur son break! Pendant ce temps je continue à utiliser le même switch pour d'autres commandes du menu (alors qu'une précédente est restée bloquée car elle n'a pas fait son retour sur le break). Entre autres commandes, il y a un moment où je vais encore utiliser le même switch pour une commande du menu qui provoquera le lancement la fonction 2, la fonction 2 qui n'a rien de particulier se termine immédiatement et revient aussitôt sur son break comme n'importe quelle autre commande (je le trace). Et c'est alors et seulement maintenant que la fonction 1 va revenir sur son break !! C'est ça qui me paraît bizarre, comment le switch du programme principal peut-il s'y retrouver quand tout à coup un de ses break récupère le retour de la fonction 1 alors qu'entre-temps ce même switch a servi pour d'autres commandes!!! Pour être plus précis: si ça se trouve le pointeur d'exécution du programme principal est encore sur les instructions qui suivent le break de retour de la fonction 2, alors qu'il faudrait qu'il soit aussi sur le break de retour de la fonction 1. A ma connaissance, le pointeur d'exécution du programme principal qui n'est pas à mon sens un programme réentrant ne peut pas avoir simultanément deux pointeurs d'exécution des instructions. Ou alors il y a un truc qui m'échappe!!

  6. #6
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par Athur Voir le message
    Ca me paraît évident,
    Effectivement, j'avais mal lu.
    Citation Envoyé par Athur Voir le message
    Enfin, comme je l'ai suggéré à la fin de mon 1er message, il me paraît peu plausible que le problème puisse venir d'un mauvais fonctionnement de la fonction 1 ou 2.
    C'est sur les OS et les compilateurs sont la première source de bug
    Citation Envoyé par Athur Voir le message
    Mais par contre, je ne sais pas si ça a été bien saisi, il y a dans cette façon de faire un problème très dérangeant au plan logique et je pencherais plutôt dans cette direction et c'est surtout sur ce point qu'un avis m'intéresse.
    Il n'y a pas de création de thread dédié ni de duplication de pointeur d'exécution dans ton dos. Le fait que tu passes toujours par le même switch vient du fait qu'une seule fonction est associée à ta classe de fenêtre. Peu importe où se trouve ta boucle de message ! La fonction de traitement est appelée par le truchement de DispatchMessage. Tu devrais mettre un point d'arrêt à ton switch et remonter pas à pas pour voir ce qu'il se passe. Mais probablement que tes 2 fonctions ont un problème de cohérence.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. problème de DLL sous visual studio 2008
    Par kira09 dans le forum C++
    Réponses: 2
    Dernier message: 12/06/2008, 12h50
  2. Problème de Dll sous windows98
    Par Nina3010 dans le forum Windows 2000/Me/98/95
    Réponses: 1
    Dernier message: 13/06/2007, 08h19
  3. Problème de lien avec wsock32.dll sous g++ (mingw32)
    Par TheShadow dans le forum Autres éditeurs
    Réponses: 3
    Dernier message: 11/04/2006, 14h43
  4. Problèmes de libération de Dll en delphi7 sous windows XP
    Par Tardiff Jean-François dans le forum Langage
    Réponses: 5
    Dernier message: 10/01/2006, 15h30

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo