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

MFC Discussion :

conteneur de la STL (problème avec DLL et COM)


Sujet :

MFC

  1. #1
    Inactif  

    Homme Profil pro
    Ingénieur test de performance
    Inscrit en
    Décembre 2003
    Messages
    1 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur test de performance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 986
    Points : 2 605
    Points
    2 605
    Par défaut conteneur de la STL (problème avec DLL et COM)
    Bonjour à tous.

    J'ai un programme qui utilise les conteneurs de la STL: string, vector, multimap, etc...

    Ce programme utilise une DLL, que j'ai remplacé par un composant COM.

    Certains conteneurs que j'utilise sont passés par référence à la DLL (et maintenant au composant COM).

    Je ne parle plus que de la DLL, car le problème est complètement identique avec le composant COM.

    Les conteneurs une fois dans la DLL, se voient attribués de nouvelles données à coup de "push_back". C'est-à-dire qu'il y a allocation de mémoire (faîte par la référence au conteneur).

    Il se trouve qu'une fois ces étapes terminées et que l'on se retrouve en dehors de la DLL, et donc dans le programme principal, ces données sont effectivement présentent au sein du conteneur.

    Sauf que si je décharge cette DLL, je n'en ai plus besoin, alors le conteneur perd ses données?????

    Il me semble alors que les allocations dynamiques de mémoire effectuées dans la DLL, sont détruites au déchargement de celle-ci.
    Je ne comprends pas trop, car normalement, la DLL s'exécute dans l'espace d'adressage du processus. Donc la référence de mon conteneur qui alloue de la mémoire, le fait dans cet espace là et ces données ne devraient disparaître que lors de l'arrêt du processus.

    Mais il n'en est rien. On dirait donc que la DLL utilise un espace d'adressage qui lui est propre et que lorsque l'on déréférence cette DLL, toutes les données allouées sur cet espace disparaîssent, alors qu'elles ont été allouées par un objet créé en dehors de cette DLL.

    Ceci est plutôt gênant. Pour COM c'est pareil lorsque l'on appelle la méthode CoUninitialize();

    J'ai vu qu'il existait des allocations de mémoire particulieres à COM, mais pour les conteneurs je ne vais pas les reprogrammer!!!

    Quelle est la méthode à utiliser? Ou est-ce qu'il est impossible de faire de l'allocation mémoire dans une DLL ou un composant COM, qui ne soit perdu lors de leur destruction?

  2. #2
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    salut,
    peut être (à verifer ) que si tes objets conteneurs sont déclarés dans la dll ,lors de la fermeture de celle-ci les conteneurs sont détruits, et les données associées avec (par le conteneur).
    il faudrait que tes conteneurs soient alloués dynamiquement .

  3. #3
    Inactif  

    Homme Profil pro
    Ingénieur test de performance
    Inscrit en
    Décembre 2003
    Messages
    1 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur test de performance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 986
    Points : 2 605
    Points
    2 605
    Par défaut
    Comme je l'ai expliqué, mais un peu vite, les conteneurs sont passés par référence à la DLL et par pointeur pour le COM (et par référence du conteneur pointé au sein du composant). Les conteneurs sont créés dans le programme, pas dans la dll ou le composant COM. Mais effectivement ils sont simplement créés.

    Donc normalement, il me semble, c'est le conteneur qui assume ses allocations de mémoire en son sein lorsque par exemple on fait un "push_back", que celles-ci soient faîtes dans le programme ou la DLL.

    Losque je quitte la DLL, les conteneurs ne sont pas détruits puisqu'ils existent et sont dans le programme principal. Ce sont les données qu'ils ont accumulées qui disparaissent. J'ai pensé à un truc tout bête mais pas viable selon moi. Faire un ".reserve" avant le passage dans la DLL. Mais ça implique de savoir la mémoire à réserver, et donc on perds l'intérêt de l'allocation dynamique.

    J'en conclu qu'il existe deux espaces d'adressage, celui du processus et celui de la DLL. Tous ceux qui a été alloués dans l'espace de la DLL sont détruits lors de la destruction de celle-ci. Il faudrait que mon conteneur alloue sa mémoire dans l'espace d'adressage du processus.

    Mais je ne suis pas sur de ce que j'avance. Pour l'instant la parade que j'utilise c'est d'allouer tout les conteneurs dans la DLL et de faire une copie dans le programme et là "no problemo".

    J'aimerais comprendre quand même ce qui se passe.

  4. #4
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Chaque module a son propre espace d'allocation, si tu veux utiliser correctement la SL il va falloir l'utiliser dans une DLL elle aussi.

    A savoir (pour VC 7.1) propriétés du projet -> C / C++ -> Génération de code -> Bibliothèque runtime -> DLL (debug) multithreaded.

    Et ça pour tous les modules de ton projet.

  5. #5
    Inactif  

    Homme Profil pro
    Ingénieur test de performance
    Inscrit en
    Décembre 2003
    Messages
    1 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur test de performance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 986
    Points : 2 605
    Points
    2 605
    Par défaut
    Citation Envoyé par Loulou24
    Chaque module a son propre espace d'allocation, si tu veux utiliser correctement la SL il va falloir l'utiliser dans une DLL elle aussi.

    A savoir (pour VC 7.1) propriétés du projet -> C / C++ -> Génération de code -> Bibliothèque runtime -> DLL (debug) multithreaded.

    Et ça pour tous les modules de ton projet.
    Si je comprends bien, alors effectivement chaque module a son propre espace d'adressage. Lorsque l'on détruit un module, toutes les données allouées dans ce module disparaissent avec. Ce qui explique le comportement de mon application. OK je peux faire avec, suffit de connaître ce comportement.

    Ce qui m'intrigue, c'est qu'un processus à sa pile d'appel, ses variables statiques, sa zone mémoire, etc...

    Ceci voudrait dire que lorsque l'on charge un module (dll ou com in_process)) alors une nouvelle zone est utilisée!!! Un peu bizarre ou un manque de connaissance de ma part.

    Par contre je vois pas le rapport avec le multithread, dans le cas ou tout se fait de façon séquentielle.

  6. #6
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Par contre je vois pas le rapport avec le multithread, dans le cas ou tout se fait de façon séquentielle
    Ici c'est le "DLL" qui est important, pas le "multithreaded" .

    En ce qui concerne les processus et leur gestion de la mémoire, j'avoue ne pas en savoir plus alors n'hésite pas à rechercher des explications plus fiables.

    Au fait est-ce que cela a résolu ton problème ?

  7. #7
    Inactif  

    Homme Profil pro
    Ingénieur test de performance
    Inscrit en
    Décembre 2003
    Messages
    1 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur test de performance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 986
    Points : 2 605
    Points
    2 605
    Par défaut
    Le problème est résolu parce que je l'ai contourné. Néanmoins je voulais comprendre ce qui se passe exactement.

    J'ai déjà commencer quelques recherches et certaines choses sont beaucoup plus claires. Pour info, des fonctions telles que "alloca" (ou "_alloca" sous win), sont des débuts de réponse...

  8. #8
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Et sans le contourner, en utilisant la CRT en DLL est-ce que ça fonctionne ? (si je suis à côté de la plaque, j'aimerais le savoir )

  9. #9
    Inactif  

    Homme Profil pro
    Ingénieur test de performance
    Inscrit en
    Décembre 2003
    Messages
    1 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur test de performance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 986
    Points : 2 605
    Points
    2 605
    Par défaut
    En fait, les DLL ou les composants COM ne peuvent pas travailler avec des références ou des pointeurs (je parle bien sur des objets complexes). Ces composants ne peuvent travailler qu'avec des adresses.

    D'ailleurs si on regarde les composants COM dans leur ensemble, ce sont souvent des adresses de pointeur d'interface que l'on passe en paramètre.

    Le problème (je pense) vient du passage des paramètres au fonction de la DLL. Ce processus doit être différent et limité (à confirmer). Il me semble avoir vu que pour les composants COM, on pouvait utiliser les références (dans le fichier .idl: déclaration [ref]) mais je n'ai pas encore approfondi le sujet.

    Je teste cet exemple et je confirme ou pas:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    typedef vector<int> VINT;
     
    VINT vInt;
    VINT* pvInt = &vInt;
     ...
    pInterface->Initialiser_le_vecteur(&pvInt);
     
    pInterface->Release();
    CoUninitialize();
     
    // vInt doit toujours contenir les données intialisées dans le composant.
    Pour mémo ce qui suit ne fonctionne pas:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    typedef vector<int> VINT;
     
    VINT vInt;
     ...
    pInterface->Initialiser_le_vecteur(&vInt);
     
    // vInt contient les données.
     
    pInterface->Release();
    CoUninitialize();
     
    // vInt ne contient plus aucunes données.
    Quoique en relisant ce dernier code je me demande si c'est vraiment un problème de passage de paramètre puisque les données existent avant l'appel de CoUninitialize();

Discussions similaires

  1. STL Problème avec une liste d'instances de class
    Par BruceBoc dans le forum SL & STL
    Réponses: 12
    Dernier message: 16/02/2007, 14h12
  2. problème avec dll de ressource
    Par adaneels dans le forum Delphi
    Réponses: 2
    Dernier message: 03/01/2007, 09h56
  3. STL : problème avec un iterateur
    Par fabienpot dans le forum SL & STL
    Réponses: 4
    Dernier message: 06/09/2006, 09h06
  4. Problème avec dll win32com
    Par jbidou88 dans le forum Langage
    Réponses: 2
    Dernier message: 28/08/2006, 14h06
  5. [STL]Problème avec map
    Par mambo dans le forum SL & STL
    Réponses: 11
    Dernier message: 27/07/2006, 15h39

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