Toujours à propos des DLL

Résolu
ArthurAuguste Messages postés 107 Date d'inscription lundi 7 février 2011 Statut Membre Dernière intervention 17 février 2018 - 13 mars 2011 à 15:08
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019 - 15 mars 2011 à 17:50
J'aurais besoin d'une explication sur le fonctionnement des dll.
Voila, dans mon programme principal qui est une simple fenêtre avec une boucle habituelle Getmessage, sur une commande passée par l'utilisateur, je suis amené à charger ma dll dans le corps du programme principal et à lui passer la main.
Cette dll contient :
- un point d'entrée commun (APIENTRY dllmain)
- Une fonction (extern "C" __declspec(dllexport) INT WINAPI), celle que j'appelle par mon programme principal
- Quelques fonctions ordinaires purement internes.
- Une callback.
- Chaque fonction de la dll a ses variables internes propres.
- Mais il y a aussi des variables globales propres à la dll et que je pensais communes à l'ensemble des fonctions de la dll.

Ma question porte sur les variables globales à la dll :
Lorsque j'initialise une variable globale de la dll de manière dynamique, par exemple lorsque je passe lors de l'appel à cette dll par le programme principal un paramètre qui est l'adresse d'un buffer du programme principal contenant du texte et que je recopie une fois pour toutes ce texte dans une variable globale propre à ma dll (je m?assure d'ailleurs ensuite que cette variable globale contient bien le texte recopié). Eh bien au bout d'un nombre assez petit d'échanges entre le prog ppal et la dll (la bcle Getmessage qui appelle automatiquement la callback), je m?aperçois que le texte que j'ai recopié dans ma variable globale de la dll et que pourtant je n'utilise plus qu'en lecture a disparu.
Ca ne change rien si je déclare la variable globale en static. Si le texte en question je le déclare manuellement au moment de la compilation comme une constante dans cette même variable globale, il ne disparaît évidemment plus.
Est-ce que ça signifie qu'entre chaque appel de la callback de la dll par la boucle Getmessage du prog ppal, la dll est réinitialisée ? (pourtant après l'avoir chargée je pensais qu'elle restait en mémoire)
Est-ce normal ? Quelle explication ? et si c'est normal, ce qui est curieux c'est que certaines variables globales à la dll initialisées dynamiquement ne disparaissent pas (n0 instance de la dll, ou handle de la fenêtre du prog ppal par exemple).
S'il y a une explication, qu'en est-il des variables propres à chaque fonction de la dll : est-ce que au moins elles, sont conservées entre chaque échange si je les déclare en static ?
Merci

11 réponses

BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
13 mars 2011 à 20:57
Il y a bien UNE dll PAR processus de chargée quand c'est un hook.

ciao...
BruNews, MVP VC++
3
cs_patatalo Messages postés 1466 Date d'inscription vendredi 2 janvier 2004 Statut Modérateur Dernière intervention 14 février 2014 2
13 mars 2011 à 18:15
salut,

L'explication la plus probable pour moi est que tu écrases des données par une erreur de code.

@++
0
ArthurAuguste Messages postés 107 Date d'inscription lundi 7 février 2011 Statut Membre Dernière intervention 17 février 2018
13 mars 2011 à 19:28
Bonjour,
Non je ne peux pas écraser, voir mon autre message: "API32 sous WIndows et appel DLL" ou j'ai écrit ceci en complément d'info (j'ai supprimé tout le code, je ne fais donc plus rien, sauf à sortir ce que contient le buffer)

Complément d'info:
Pour mieux tester, je ne fais plus rien dans ma callback, je ne fais juste qu'imprimer par MessageBox le buffer pour voir à quel moment il disparaît, puis return immédiat sur CallNextHookEx.
En fait tant que je tape des caractères sur la fenêtre active de mon programme principal (ou ce qui est bizarre dans la fenêtre CMD de MSDOS) mon buffer ne disparaît pas, dès que je tape des caractères sur d'autres fenêtres actives que ces deux premières fenêtres mon buffer disparaît (je sors des MessageBox vides). Mais lorsque je reviens sur une des deux premières fenêtres, mon buffer réapparaît un peu comme s'il y avait plusieurs versions de DLL qui tournaient.
Il doit y avoir un truc que je n'ai pas compris...
0
ArthurAuguste Messages postés 107 Date d'inscription lundi 7 février 2011 Statut Membre Dernière intervention 17 février 2018
14 mars 2011 à 08:57
Merci pour la précision,
Saurais-tu où je peux trouver des explications documentaires sur ce sujet ?
Y aurait-il à ton avis une solution pour conserver les variables globales de la dll une fois celles-ci initialisées ?
(Rappel du fonctionnement: une fois le hook lancé, la boucle getmessage de mon prog ppal (ma fenêtre) dirige les messages concernant les appuis sur les touches vers la callback qui se trouve dans ma dll).
Est-ce que je me trompe si je dis que s'il y a une dll par processus, les variables locales aux fonctions de la dll déclarées en static ne sont pas non plus conservées ?
Est-ce qu'à ton avis ça changerait quelque chose si je transfère la boucle getmessage (pour les messages concernant les touches) dans ma dll avec la callback ?
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
14 mars 2011 à 10:26
Les touches clavier sont à récupérer par un hook clavier, pas de GetMessage à faire.

Le partage des variables peut se faire (entre autre) par une section 'SHARED'.

Se reporter aux nombreux exemples de hook que j'ai postés ici.

ciao...
BruNews, MVP VC++
0
ArthurAuguste Messages postés 107 Date d'inscription lundi 7 février 2011 Statut Membre Dernière intervention 17 février 2018
14 mars 2011 à 19:21
Merci pour tes explications.
Entre-temps j'ai fait marcher mon appli en sauvegardant les données sensibles dans un fichier en sortie de callback et en les récupérant à l'entrée de la callback, j'ai mis les données susceptibles de changer et de resservir à l'exécution suivante de la DLL dans une union sous la forme suivante:
union DONNEES // structure permettant de mapper les données
{
char image[Tailimage];
struct DETAIL
{
HHOOK clehook; // clé hook
BOOL SHIFTDOWN;
BOOL ALTDOWN;
BOOL CTRLDOWN;
BOOL MAJUSCULE;
HWND lastactivfen;
DWORD Lastlongtitre;
UINT nbBACK;
char Pnomfichier[100];
} Monimage;
} Mesdonnees;
Ainsi je lis et j'écris tout en une seule fois dans: Mesdonnees.image
Ca marche très bien maintenant, mais ça n'est pas très satisfaisant pour l'esprit d'être obligé de faire des E/S.
Je vais aller voir si je trouve de la doc sur les sections "SHARED" as-tu dans tes développement un exemple court et facile à comprendre d'utilisation de ces sections "SHARED" ?
Merci
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
14 mars 2011 à 21:51
http://www.cppfrance.com/code.aspx?id=17387

Regarde dans le CPP de la DLL.

ciao...
BruNews, MVP VC++
0
ArthurAuguste Messages postés 107 Date d'inscription lundi 7 février 2011 Statut Membre Dernière intervention 17 février 2018
14 mars 2011 à 22:41
Ok,
Si j'ai bien compris la zone partagée et qui, donc, n'est pas réinitialisée d'une exécution à l'autre est encadrée par les bornes:
#pragma data_seg("Shared")
et
#pragma data_seg()

Merci

P.S. Simple demande de précision: est-ce que le mot "Shared" est un mot réservé obligatoire pour préciser que la zone qui suit sera partagée ou bien est-ce simplement un nom donné à cette zone et dans ce cas on peut l'appeler n'importe comment?
"Toto" ou "Commun" d'ailleurs si c'était un nom de zone, je ne vois pas d'autres endroits où on y fait référence.
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
15 mars 2011 à 10:17
La source sur laquelle je t'ai envoyé date un peu.
Sur les versions recentes de VC++, il convient d'employer cette syntaxe:

#pragma section("SctnShare",read,write,shared)

#pragma data_seg("SctnShare")
HWND hmain = 0;
#pragma data_seg()

En meme temps, tu as ta reponse.

ciao...
BruNews, MVP VC++
0
ArthurAuguste Messages postés 107 Date d'inscription lundi 7 février 2011 Statut Membre Dernière intervention 17 février 2018
15 mars 2011 à 16:27
Merci encore,
Est-ce que je peux me permettre une ultime question :
Tu as dit dans un message précédent que pour un hook quelconque (le mien c'est un hook clavier), la boucle Getmessage ne servait à rien. Je ne demande qu'à te croire, cependant dans mon cas, j'ai un programme principal qui est une simple fenêtre qui a sa boucle Getmessage pour analyser les choix dans le menu de l'utilisateur. C'est aussi ce même programme principal qui charge et lance la DLL qui fait le hook et qui contient la callback.
Pour l'instant tout fonctionne, mais si j'enlève la boucle Getmessage du programme principal, mon programme principal se termine, il disparaît des processus actifs avec sa dll et je n'ai plus rien qui tourne !
Si j'enlève la boucle Getmessage du programme principal, parce que effectivement après avoir lancé la dll je n'en ai plus besoin, comment faut-il faire pour que le programme principal ne se termine pas et que je ne perde pas la dll avec sa fonction hook.
J'espère ne plus t?ennuyer après.
R.G.
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
15 mars 2011 à 17:50
Je pensais que tu parlais d'un GetMessage() dans la fonction hook de la dll.

ciao...
BruNews, MVP VC++
0
Rejoignez-nous