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

C++Builder Discussion :

Souci en mémoire lors de l'inclusion d'une DLL en C ?


Sujet :

C++Builder

  1. #1
    Membre régulier Avatar de benj63
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Mai 2002
    Messages
    207
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 207
    Points : 99
    Points
    99
    Par défaut Souci en mémoire lors de l'inclusion d'une DLL en C ?
    Bonjour à tous,

    J'ai créé une DLL à partir d'un code source en C, en utilisant l'assistant "Expert DLL" de Borland C++ Builder 6.

    J'ai inclus au projet de la DLL la librairie "memmgr.lib" comme cela est conseillé.

    Pour compiler cette DLL, j'ai créé un .HPP contenant une seule fonction :
    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
    #ifndef NnDllH
    #define NnDllH
     
    #ifdef __DLL__
    #define IMPORT_EXPORT __declspec(dllexport)
    #else
    #define IMPORT_EXPORT __declspec(dllimport)
    #endif
     
    #if !defined(_POINT_STRUCT)
    #define _POINT_STRUCT
    typedef struct {
        double x;
        double y;
        double z;
    } point;
    #endif
     
    IMPORT_EXPORT void InterpolationNaturalNeighbor(int nin, point *pin, double xmin, double xmax, double ymin, double ymax, int nx, int ny, int type_interpolation, int nout, point *pout);
     
    #endif
    Lorsque j'utilise cette DLL dans un projet C++, j'inclus le .LIB créé lors de la compilation de la DLL, et j'inclus également le HPP que je suis obligé de un peu modifier pour ne pas avoir un "unresolved external" lors de la compilation :
    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
    #ifndef NnDllH
    #define NnDllH
     
    #if !defined(_POINT_STRUCT)
    #define _POINT_STRUCT
    typedef struct {
        double x;
        double y;
        double z;
    } point;
    #endif
     
    extern "C" __declspec(dllimport) __stdcall void _InterpolationNaturalNeighbor(int nin, point *pin, double xmin, double xmax, double ymin, double ymax, int nx, int ny, int type_interpolation, int nout, point *pout);
     
    #endif
    Déjà, est-ce que cela est correct ? Est-ce qu'il n'est pas déconseillé de mêler DLL en C et code source en C++ ?


    Jusqu'à présent, je n'avais pas rencontré de problème en utilisant ma DLL et mon LIB dans des projets en C++. Jusqu'à aujourd'hui, où j'ai créé plein de classes dans un gros projet, et lorsque j'appelle ma fonction _InterpolationNaturalNeighbor(...) dans une des fonctions d'une de mes classes, mon programme plante à la sortie de l'appel de cette fonction : toute la mémoire a l'air en vrac, l'instance de ma classe n'existe même plus en mémoire, tout est cassé

    Etant donné que la fonction en C que j'utilise dans la DLL est normalement exempte de fuites mémoires (puisque ce n'est pas moi qui l'ait codée, c'est une référence sur le web), je soupçonne que ce soit le mélange C/C++ qui soit à l'origine de ce souci... La fonction de la dll contient notamment des malloc... Ceux-ci ne risquent-ils pas, par exemple, de prendre des emplacements mémoire déjà alloués par mes classes de mon projet principal ?

    Merci pour vos avis !!

  2. #2
    Membre régulier Avatar de benj63
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Mai 2002
    Messages
    207
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 207
    Points : 99
    Points
    99
    Par défaut
    Bon, j'ai fait des tests : dans ma DLL en C, j'ai créé une fonction qui ne fait rien du tout, sans aucun paramètre.

    Eh bien même souci : juste après l'appel de ma fonction, j'ai un "violation d'accès" dans la classe en C++ qui l'appelle

    Donc on peut écarter le possible problème de fuite mémoire dans la fonction, le problème de malloc qui viendrait écraser d'autres espaces mémoires... Je commence à me dire que ça vient du fait que la DLL soit en C et de mon micmac avec des .HPP différents...

    Qu'en pensez-vous ??

  3. #3
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2005
    Messages
    401
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Seine Maritime (Haute Normandie)

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 401
    Points : 578
    Points
    578
    Par défaut
    Hello,

    J'ai inclus au projet de la DLL la librairie "memmgr.lib" comme cela est conseillé.
    Est-ce que ça veut dire que tu prévois de créer les points pin et pout dans l'exe pour les libérer dans la dll, ou de les créer dans la dll pour les libérer dans l'exe ? Si ce n'est pas le cas, tu n'as pas besoin de memmgr.lib.

    Ensuite (c'est du pinaillage) tu aurais dû créer un .h, et pas un .hpp. Les .hpp sont propres à Builder, et représentent le fichier d'inclusion associé à un .pas...

    Mais le problème doit être ailleurs...
    Lorsque j'utilise cette DLL dans un projet C++, j'inclus le .LIB créé lors de la compilation de la DLL, et j'inclus également le HPP que je suis obligé de un peu modifier pour ne pas avoir un "unresolved external" lors de la compilation :
    Ça c'est pas normal, ça casse l'intérêt d'avoir un .h partagé entre la dll et l'exe....
    Voici un .h que je te propose d'utiliser:
    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
    #ifndef NnDllH
    #define NnDllH
    
    #ifdef __DLL__
    #define IMPORT_EXPORT __declspec(dllexport)
    #else
    #define IMPORT_EXPORT extern "C" __declspec(dllimport)
    #endif
    
    #if !defined(_POINT_STRUCT)
    #define _POINT_STRUCT
    typedef struct {
        double x;
        double y;
        double z;
    } point;
    #endif
    
    IMPORT_EXPORT void __stdcall InterpolationNaturalNeighbor(int nin, point *pin, double xmin, double xmax, double ymin, double ymax, int nx, int ny, int type_interpolation, int nout, point *pout);
    
    #endif
    Dans le .c de ta dll:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void __stdcall InterpolationNaturalNeighbor(int nin, point *pin, double xmin, double xmax, double ymin, double ymax, int nx, int ny, int type_interpolation, int nout, point *pout)
    {
    ...
    }
    Le but du extern "C" est justement de faire le pont entre ta dll en C et ton exe en C++.....

    Pour le __stdcall: Ton exe et ta dll ont des conventions d'appel par défaut qui sont définies dans les options du projet (onglet Options avancées du compilateur). Ce n'est pas gènant en soi qu'elles soient différentes, du moment que les conventions d'appel pour les fonctions partagées (ici InterpolationNaturalNeighbor) sont toujours claires et correctement définies....
    Il se trouve justement que les violations d'accès en sortie de dll sont très souvent dues à des conventions d'appel incohérentes entre la dll et l'exe...

    Déjà, est-ce que cela est correct ?
    Pour moi non, cf. les corrections proposées.
    Est-ce qu'il n'est pas déconseillé de mêler DLL en C et code source en C++ ?
    Non, il faut juste bien expliquer à l'exe en C++ qu'il doit attaquer une DLL en C.
    Etant donné que la fonction en C que j'utilise dans la DLL est normalement exempte de fuites mémoires (puisque ce n'est pas moi qui l'ait codée, c'est une référence sur le web), je soupçonne que ce soit le mélange C/C++ qui soit à l'origine de ce souci... La fonction de la dll contient notamment des malloc... Ceux-ci ne risquent-ils pas, par exemple, de prendre des emplacements mémoire déjà alloués par mes classes de mon projet principal ?
    Il y aura un risque justement si tu utilises memmgr.lib, puisque dans ce cas tu partages le gestionnaire de mémoire entre ton exe et ta dll. Sans memmgr.lib, l'exe et la dll se débrouillent chacun de leur côté avec leur propre pool de mémoire (ça ne veut pas dire que tu n'auras jamais de problème, mais au moins ça en enlève une source !)

  4. #4
    Membre régulier Avatar de benj63
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Mai 2002
    Messages
    207
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 207
    Points : 99
    Points
    99
    Par défaut
    Alors là je dis MERCI totoche76

    Je n'ai plus mes problèmes mémoire à la sortie de la DLL dans mon programme C++ !

    Citation Envoyé par totoche76 Voir le message
    Est-ce que ça veut dire que tu prévois de créer les points pin et pout dans l'exe pour les libérer dans la dll, ou de les créer dans la dll pour les libérer dans l'exe ? Si ce n'est pas le cas, tu n'as pas besoin de memmgr.lib.
    Non, mes new et delete sont dans mon exe, le dll ne crée ou supprime rien. Donc pas besoin du memmgr.lib, ok !

    Citation Envoyé par totoche76 Voir le message
    Ensuite (c'est du pinaillage) tu aurais dû créer un .h, et pas un .hpp. Les .hpp sont propres à Builder, et représentent le fichier d'inclusion associé à un .pas...
    Ca ne coûte rien de changer, j'ai corrigé ça !

    Citation Envoyé par totoche76 Voir le message
    Voici un .h que je te propose d'utiliser:
    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
    #ifndef NnDllH
    #define NnDllH
    
    #ifdef __DLL__
    #define IMPORT_EXPORT __declspec(dllexport)
    #else
    #define IMPORT_EXPORT extern "C" __declspec(dllimport)
    #endif
    
    #if !defined(_POINT_STRUCT)
    #define _POINT_STRUCT
    typedef struct {
        double x;
        double y;
        double z;
    } point;
    #endif
    
    IMPORT_EXPORT void __stdcall InterpolationNaturalNeighbor(int nin, point *pin, double xmin, double xmax, double ymin, double ymax, int nx, int ny, int type_interpolation, int nout, point *pout);
    
    #endif
    Dans le .c de ta dll:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void __stdcall InterpolationNaturalNeighbor(int nin, point *pin, double xmin, double xmax, double ymin, double ymax, int nx, int ny, int type_interpolation, int nout, point *pout)
    {
    ...
    }
    Le but du extern "C" est justement de faire le pont entre ta dll en C et ton exe en C++.....
    J'ai corrigé le .h comme tu me l'as indiqué et je n'ai plus de "unresolved external"

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

Discussions similaires

  1. Réponses: 8
    Dernier message: 17/09/2007, 20h16
  2. Réponses: 2
    Dernier message: 30/05/2006, 09h02
  3. Réponses: 4
    Dernier message: 16/05/2006, 23h15
  4. [MFC] Problèmes d'inclusion d'une DLL
    Par CaptnB dans le forum MFC
    Réponses: 1
    Dernier message: 12/05/2006, 18h01
  5. Inclusion d'une DLL dans un exe?
    Par luareon22 dans le forum MFC
    Réponses: 10
    Dernier message: 29/08/2005, 12h08

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