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 :

Toujours à propos des DLL


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 Toujours à propos des DLL
    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 aussi 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

  2. #2
    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 Complément d'info
    Bonjour,
    En 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 que maintenant j'initialise au 1er appel avec le nom du fichier (et non plus avec son adresse) pour voir à quel moment il disparaît, puis return immédiat sur CallNextHookEx (donc pas possible de suspecter un écrasement de code puisque je ne fais plus rien!)
    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...

  3. #3
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Ta DLL est utilisée par plusieurs programmes, les données (même globales) de ta DLL sont spécifiques à chacuns de tes programmes, ce ne sont pas des variables partagées entre les différentes instances des programmes qui utilisent ta DLL. Le segment de mémoire des données de ta DLL est dupliqué entre chacunes des applications. Il n'y a que le segment de code qui est le même.

    Si tu veux avoir des données partagées entre tous les programmes qui utilisent ta DLL, il va falloir passer par un support partageable ==> fichier (avec tous les problèmes que cela peut comporter) ou mémoire partagée (à mon avis plus pèrenne).
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

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

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

    Informations forums :
    Inscription : Septembre 2007
    Messages : 923
    Par défaut
    Quand tu clique sur d'autres fehnêtres tu veux dire des fenêtres d'un autres programmes (donc d'autres processus ?

    car il faut savoir sur les dll que :
    - seule la partie code est commune à tous les processus.
    - pour la partie données, chaque process à ses propres instances des données globales et static. elles ne sont donc pas partagées entre les différents processus. Si jamais tu arrive quand meme à relire une donnée depuis un autre processus, c'est uniquement par chance, dangereux (tu risque une exception) et bancale.

    Pour partager des données globales d'une dll entre plusieurs processus :
    http://msdn.microsoft.com/en-us/libr...8VS.85%29.aspx

  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 Info en plus
    Merci pour vos explications.
    De mon côté je pensais que ma DLL n'était utilisée que dans un seul programme, mon programme principal (simple fenêtre avec une boucle Getmessage) dans lequel je charge ma DLL. La boucle Getmessage de mon seul programme aiguille les messages de crochetage des touches du clavier vers la callback qui est dans la DLL.
    Si j'ai bien compris ce que vous voulez dire c'est que lorsque je tape sur des touches quand je suis sur une fenêtre qui n'est pas à moi (par exemple d'un site quelconque du net, donc pas un autre programme à moi), c'est une version dupliquée de ma DLL qui s'exécute ce qui explique que les données sont réinitialisées.
    1.- Pouvez-vous me confirmer SVP que c'est bien ça qu'il faut comprendre ?
    Si c'est bien ça, j'ai une question qui me vient à l'esprit: dans le cas effectivement où je tape sur des touches devant une fenêtre du net (donc qui n'est pas un programme à moi), si seule une version dupliquée de ma DLL s'exécute sans mon programme principal (puisque la fenêtre de mon programme principal n'est plus active) :
    2.- où se trouve la boucle Getmessage qui aiguille les messages de crochetage des touches vers cette version de ma DLL?
    Serait-ce la boucle Getmessage de la fenêtre du net (qui n'est donc pas à moi) ?
    Enfin avant que vous ne répondiez, j'avais anticipé la solution en mettant toutes les données de ma dll qui sont initialisées dynamiquement et qui sont susceptibles d'être réutilisées d'une exécution à l'autre, dans un fichier de travail que j'initialise au 1er appel de la DLL, je le lis à chaque début de ma callback et je le sauvegarde à chaque sortie de callback.
    C’est assez simple en utilisant une union:
    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
    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;
    Ce qui me permet d'écrire ou de lire d'un coup en faisant les E/S sur uniquement: Mesdonnees.image.
    Et depuis tout baigne nickel !
    Toutefois cette méthode brutale qui consiste à faire des E/S n'est pas très satisfaisante pour l'esprit.
    3.- Est-ce que d'autres méthodes (que je ne connais pas très bien) comme par exemple le mapping ou les segments pourraient marcher dans mon cas? (au quel cas il faudrait que je me documente)

    Encore merci pour vos réponses

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

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

    Informations forums :
    Inscription : Septembre 2007
    Messages : 923
    Par défaut
    Oui c'est une version dupliquée pour ce qui est des données uniquement.
    Le code lui est partagé car ne change pas, ce serait de la perte en terme d'espace mémoire que de le dupliquer.
    Il ne faut pas voir la dll comme une seule chose mais faite de 2 composants. -Une partie Code unique pour tous les programme qui lui sont liés
    -Une partie Données propre à chaque programme (donc non partagée)

    Maintenant, pourquoi ça marche aussi dans les autres applications :
    Dans ta fonction SetWindowsHookEx, en 4ieme paramètre*, le threadId, tu as passé NULL, ce qui veut dire que tu as créé un hook global. Cela implique quoi ?

    Qu'a chaque fois que tu active une programme (en le passant en avant plan), il va se lier à la DLL et donc en créer une instance (quand je dis chaque fois, c'est une fois par programme bien entendu). La dll va hooker sa boucle de message et intercepter les appuis clavier sur cette application. nul besoin de boucle de message dans la dll, chaque appuie sur une touche déclanchera la fonction de callback qui va traiter l'info, puis ensuite appeler si besoin le traitement normal (avec CallNextHookEx). CallNextHookEx qui peut très bien déboucher sur une autre dll de hook, tu peux les chaîner.

    Au final, ta dll sera liée à tous les programme que tu as utilisé. il n'y aura en mémoire qu'une seule instance de code, mais autant d'instance data que de programmes liés.
    D'ou la necessité si tu as vraiment besoin de partager des données d'utiliser un mécanisme d'échanges dans ceux que tu as cité. après c'est le choix du développeur. Perso, je préfère le mapping.

    * En précisant un Id de thread dans le 4ieme paramètre de SetWindowsHookEx, ça te permet de choisir de ne hooker que les touches provenant de la boucle de message d'un thread précis.

  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 Partage des données
    Merci beaucoup pour cette réponse très complète.

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

Discussions similaires

  1. à propos des .dll .ocx utilisés par un programme VB6
    Par HRS dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 22/11/2012, 13h34
  2. A propos des DLL (sécurité, injection ..)
    Par hh-cx dans le forum Windows
    Réponses: 3
    Dernier message: 21/12/2010, 17h15
  3. Questions à propos des dll
    Par sansblague dans le forum C++
    Réponses: 3
    Dernier message: 14/08/2007, 19h00
  4. VBA, Graphique : Toujours à propos des ranges discontinus ..
    Par CCHEVALIER dans le forum Macros et VBA Excel
    Réponses: 9
    Dernier message: 28/09/2005, 09h15
  5. A propos des modèles d'objet (avec sources)
    Par DevX dans le forum C++Builder
    Réponses: 14
    Dernier message: 01/12/2002, 12h22

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