Toujours à propos des DLL [Résolu]

ArthurAuguste 107 Messages postés lundi 7 février 2011Date d'inscription 17 février 2018 Dernière intervention - 13 mars 2011 à 15:08 - Dernière réponse : BruNews 21054 Messages postés jeudi 23 janvier 2003Date d'inscription 7 novembre 2014 Dernière intervention
- 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
Afficher la suite 

Votre réponse

11 réponses

Meilleure réponse
BruNews 21054 Messages postés jeudi 23 janvier 2003Date d'inscription 7 novembre 2014 Dernière intervention - 13 mars 2011 à 20:57
3
Merci
Il y a bien UNE dll PAR processus de chargée quand c'est un hook.

ciao...
BruNews, MVP VC++

Merci BruNews 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 70 internautes ce mois-ci

Commenter la réponse de BruNews
cs_patatalo 1466 Messages postés vendredi 2 janvier 2004Date d'inscription 14 février 2014 Dernière intervention - 13 mars 2011 à 18:15
0
Merci
salut,

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

@++
Commenter la réponse de cs_patatalo
ArthurAuguste 107 Messages postés lundi 7 février 2011Date d'inscription 17 février 2018 Dernière intervention - 13 mars 2011 à 19:28
0
Merci
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...
Commenter la réponse de ArthurAuguste
ArthurAuguste 107 Messages postés lundi 7 février 2011Date d'inscription 17 février 2018 Dernière intervention - 14 mars 2011 à 08:57
0
Merci
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 ?
Commenter la réponse de ArthurAuguste
BruNews 21054 Messages postés jeudi 23 janvier 2003Date d'inscription 7 novembre 2014 Dernière intervention - 14 mars 2011 à 10:26
0
Merci
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++
Commenter la réponse de BruNews
ArthurAuguste 107 Messages postés lundi 7 février 2011Date d'inscription 17 février 2018 Dernière intervention - 14 mars 2011 à 19:21
0
Merci
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
Commenter la réponse de ArthurAuguste
BruNews 21054 Messages postés jeudi 23 janvier 2003Date d'inscription 7 novembre 2014 Dernière intervention - 14 mars 2011 à 21:51
0
Merci
http://www.cppfrance.com/code.aspx?id=17387

Regarde dans le CPP de la DLL.

ciao...
BruNews, MVP VC++
Commenter la réponse de BruNews
ArthurAuguste 107 Messages postés lundi 7 février 2011Date d'inscription 17 février 2018 Dernière intervention - 14 mars 2011 à 22:41
0
Merci
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.
Commenter la réponse de ArthurAuguste
BruNews 21054 Messages postés jeudi 23 janvier 2003Date d'inscription 7 novembre 2014 Dernière intervention - 15 mars 2011 à 10:17
0
Merci
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++
Commenter la réponse de BruNews
ArthurAuguste 107 Messages postés lundi 7 février 2011Date d'inscription 17 février 2018 Dernière intervention - 15 mars 2011 à 16:27
0
Merci
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.
Commenter la réponse de ArthurAuguste
BruNews 21054 Messages postés jeudi 23 janvier 2003Date d'inscription 7 novembre 2014 Dernière intervention - 15 mars 2011 à 17:50
0
Merci
Je pensais que tu parlais d'un GetMessage() dans la fonction hook de la dll.

ciao...
BruNews, MVP VC++
Commenter la réponse de BruNews

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.