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++

  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.

  7. #7
    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)
    Je ne suis pas sûr d’avoir tout compris, par ailleurs je n’ai pas encore utilisé le debugging sous cpp builder. Merci en tout cas d'avoir eu la patience de dialoguer jusqu'ici. Je vais voir si je peux faire quelque chose de plus, mais, a prirori, je ne vois pas trop quoi car en fait derrière le break du switch je ne fais plus rien, je ne maîtrise donc plus, c’est windows qui gère et ma fenêtre devrait être en attente d’une action de l’utilisateur sur le menu. Pour simplifier la boucle getmessage de mon programme principal (ma fenêtre) envoie par sa dispatchmessage tous les messages sur une callback standard selon le schéma habituel ci-dessous :
    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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    while(GetMessage( &message, NULL, 0, 0))
    	{
    		TranslateMessage( &message ); 
    		DispatchMessage( &message ); 
    	}
    LRESULT CALLBACK analysemessage( HWND clefenetre, UINT IDMsg, WPARAM wParam, LPARAM lParam ) 
    { 
    	switch(IDMsg)
    	{ 
    		case  WM_LBUTTONDBLCLK:
    			traitement double clic
    			break;
    		case WM_COMMAND:
    			switch(LOWORD(wParam))
    			{
    				case Ext_STARTDLL :
    					chargement de la dll et lancement de la function 1
    					Messages( "je passe set", "SORTIE" ); // traçage fin de fonction 1
    					break;
    				case Ext_STOPDLL :
    					lancement de la function 2
    					Messages( "je passe stop", "SORTIE" ); // traçage fin de fonction 2
    					break;
    				case Ext_LIREF :
    					traitement suivant
    					break;
    				case Ext_MesConsole :
    					traitement suivant
    					break;
    			};
    			break;
    		case WM_CLOSE :
    			DestroyWindow( clefenetre );
    			break;
    		case WM_DESTROY :
    			PostQuitMessage(0);
    			break;
    		default :
    			return DefWindowProc( clefenetre, IDMsg, wParam, lParam );
    	};
    	return 0;
    }
    On voit peut-être mieux ici que lorsque la fonction 1 se termine je trace puis je tombe sur le break, puis exactement comme pour les autres commandes je sors de la callback et je ne maîtrise plus rien. Comme pour les autres commandes, quand elles ont été traitées, ma fenêtre devrait être en attente d’une action de l’utilisateur sur le menu (sauf pour close et destroy évidemment).
    Bon, si un jour je trouve quelque chose, je reviendrai sur cette discussion car en fait je peux aussi me contenter du fonctionnement actuel (même si ça tue ma fenêtre, je peux toujours la relancer). C'était simplement que j'aime bien comprendre ce qui se passe, surtout lorsque la réaction du système me surprend...
    Cordialement,

  8. #8
    Membre très actif Avatar de nirgal76
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2007
    Messages
    924
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 924
    Par défaut
    Si vraiment, ce que tu veux c'est juste attraper les touches clavier, vaut mieux faire un hook clavier en low level :
    SetWindowsHookEx(WH_KEYBOARD_LL,....
    Chaque appuie déclenchera la fonction de callback du hook et nul besoin d'une usine à gaz à boucle de message dans la dll.
    - une fonction "1" dans la dll qui install le hook (avec une fonction "3" de callback).
    - en cas de frappe clavier, la fonction "3" de callback (dans la dll) se déclenche.
    - une fonction "2" qui le désinstall le hook.

    En cpp builder, ça marche ici depuis plus de 10 ans en production (pour intercepter dans cpp builder les appuies clavier effectué dans Excel)

    Ta dll fait parti du même thread que ton exécutable. Rien que pour ça, ta logique d'avoir 2 boucles de messages (qui traite donc le même thread) dans chacun des fichiers est vouée à l'échec.

    Pour info, ce n'est pas parce que tu as 2 boucle de message que tu fais du multiprocessus, ni meme du multithreading d'ailleurs. Je pense (je n'ai même aucun doute la dessus) que tu n'as pas compris les notions de process et de thread (ni de callback d'ailleurs). Ce n'est pas méchamment que je le dis (en tout cas, ce n'est pas mon esprit actuel), je veux juste insister sur le fait que tu devrais plus te documenter sur ces sujets avant de te lancer dans ce genre de code.

  9. #9
    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
    Ta fonction analysemessage est-elle réentrante ? Utilise-t-elle sur des variables globales ou statiques ?

  10. #10
    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)
    Ma fonction analysemessage à mon sens n'est pas réentrante puisqu'il s'agit d'une fenêtre ordinaire et elle utilise des variables globales.
    Je vais essayer ce que me propose nirgal76, sauf que dans mon API32 je n'ai que le paramètre de HOOK que j'ai utilisé cad: WH_KEYBOARD, je ne vois pas le low level (WH_KEYBOARD_LL), mais je ne pense pas que ça gêne. Si j'ai bien compris, il me suffit d'enlever la boucle de messages dans la dll (fonction 1) et de transformer la callback d'analyse des messages (qui était dans la fonction 1) en point d'entrée supplémentaire de ma dll.

  11. #11
    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
    Ma fonction analysemessage à mon sens n'est pas réentrante puisqu'il s'agit d'une fenêtre ordinaire et elle utilise des variables globales.
    le plantage peut venir de là.
    Citation Envoyé par Athur Voir le message
    Si j'ai bien compris, il me suffit d'enlever la boucle de messages dans la dll (fonction 1) et de transformer la callback d'analyse des messages (qui était dans la fonction 1) en point d'entrée supplémentaire de ma dll.
    Je pense que supprimer la boucle de message suffit puisque tu fournis la fonction de callback au moment où tu installe le hook.

  12. #12
    Membre très actif Avatar de nirgal76
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2007
    Messages
    924
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 924
    Par défaut
    Citation Envoyé par Athur Voir le message
    Ma fonction analysemessage à mon sens n'est pas réentrante puisqu'il s'agit d'une fenêtre ordinaire et elle utilise des variables globales.
    Je vais essayer ce que me propose nirgal76, sauf que dans mon API32 je n'ai que le paramètre de HOOK que j'ai utilisé cad: WH_KEYBOARD, je ne vois pas le low level (WH_KEYBOARD_LL), mais je ne pense pas que ça gêne. Si j'ai bien compris, il me suffit d'enlever la boucle de messages dans la dll (fonction 1) et de transformer la callback d'analyse des messages (qui était dans la fonction 1) en point d'entrée supplémentaire de ma dll.
    Effectivement, tu enleve cette boucle de message de la dll. elle est inutile. c'est justement le but de la fonction de callback du hook clavier, d'être appelé de façon évènementielle lors de l'appuie d'une touche, nul besoin de rester à tourner dans la DLL (en plus d'être redondant et donc de se percuter avec la boucle de message de l'exécutable).
    En général, s'il faut une boucle de message dans une dll, on créé une fenêtre caché à laquelle on associe cette boucle (gestion de timer dans la dll par exemple).
    Et la fonction de callback du hook n'a pas obligation d'être un point d'entrée de la dll, la déclarer en fonction globale dans la dll suffit.
    (Et n'oublie pas le CallNextHookEx en fin de callback pour que le traitement normal des touches soit effectué).
    Et tu peux simplifier
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    	if(UnhookWindowsHookEx(clehook))
    	{	
    		return true;
    	} else
    	{
    		return false;
    	}
    en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    	return UnhookWindowsHookEx(clehook);

    pour le WH_KEYBOARD_LL :
    http://msdn.microsoft.com/en-us/libr...8VS.85%29.aspx
    Bizarre que tu ne l'ai pas dans tes .h d'API. Car je l'utilisais dejà sous bcb 6 qui date pas mal.
    Sous quel IDE tu développe ?

  13. #13
    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 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 : Sélectionner tout - Visualiser dans une fenêtre à part
    extern "C" __declspec(dllexport) DWORD WINAPI SetHook(LPVOID lpParameter){}
    Le début de ma fonction 2 commençait ainsi ::
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    extern "C" __declspec(dllexport) DWORD WINAPI StopHook(){}
    J’ai simplement modifié le début de la fonction 1 ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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,

  14. #14
    Membre très actif Avatar de nirgal76
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2007
    Messages
    924
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 924
    Par défaut
    Citation Envoyé par Athur Voir le message
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    extern "C" __declspec(dllexport) DWORD WINAPI SetHook(LPVOID lpParameter){}
    Le début de ma fonction 2 commençait ainsi ::
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    extern "C" __declspec(dllexport) DWORD WINAPI StopHook(){}
    J’ai simplement modifié le début de la fonction 1 ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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,
    Si ta dll attendait un paramètre mais que tu n'en fournis pas, l'erreur est là, ça décalait la pile (ou la mémoire selon la convention d'appel utilisée) car la fonction dépile un paramètre mais rien n'a été placé dans la pile par l'exécutable lors de l'appel et tout se décale => bug (car sinon, passer un paramètre est tout à fait autorisé, tu peux laisser (LPVOID lpParameter) à condition de passer un paramètre lors de l'appel à la fonction, genre SetHook(NULL)). Si tu n'as pas besoin de paramètre, met (void) plutôt que ().
    Tu ne prends pas de notre temps ne t'inquiete pas, on est là pour aider et être aider, c'est le but d'un forum, échanger

  15. #15
    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 Suite
    Merci pour tout,
    J'ai fait, je crois, à peu près tous les tests.
    La dll simplifiée (sans boucle interne) marche avec mon programme principal, mais ne fonctionne pas si appel simple par rundll32 (rundll32 se termine immédiatement ce qui paraît logique).
    Ma dll initiale (avec boucle interne) marche maintenant dans les deux cas: avec mon programme principal et avec rundll32. Je ne sais pas trop comment le système s'en sort mais visiblement il n'a pas l'air de se mélanger les pinceaux avec la boucle du programme principal pour l'analyse des commandes du menu et la boucle interne à la dll pour pièger les touches du clavier. Si les messages arrivaient sur ma callback d'analyse des touches par deux sources différentes (boucle prog principal + boucle DLL) il me semble que je dupliquerais les touches or ce n'est pas le cas.
    J'ai rajouté le suffixe _LL à WH_KEYBOARD et le compilateur ne m'a pas sorti d'injure, visiblement il a l'air de le prendre, ça doit être ma doc de l'api 32 qui doit être trop vieille, j'ai une date de modification de win32.hlp qui remonte à novembre 1996.
    Le problème des 2 boucles et de la façon dont le système s'en sort reste un peu en suspens. En fait comme je n'utilise pas la même structure MSG pour chacune des boucles, il faudrait que j'aille voir quelle est la structure qui contient le wparam et lowparam qui arrivent sur ma callback avec cependant le problème que de la dll je n'ai pas accès à la structure MSG du programme principal.
    Cordialement,

+ 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