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 Discussion :

problème libération mémoire après une DLL


Sujet :

C

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 298
    Points : 886
    Points
    886
    Par défaut problème libération mémoire après une DLL
    Bonjour,

    j'ai fait un programme en C sous Visual C++ 6.0. Tout se passe bien lors de l'exécution. Lors de la libération de la mémoire j'appelle la fonction suivante :

    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
     
    void DestroyResultatFit(ResultatFit ** rfit)
    {
      if(*rfit != NULL)
      {
        DestroyGRC(&(*rfit)->grc);
        DestroyGIF(&(*rfit)->gif);
        DestroyGSF(&(*rfit)->gsf);
        DestroyPLC(&(*rfit)->plc);
        DestroyGRF(&(*rfit)->grf);
        DestroyDCN(&(*rfit)->dcn);
        DestroyExtrapolation(&(*rfit)->extra);
    	DestroyDFLU(&(*rfit)->dflu);
    	DestroyCyclesGSFGRCGRF(&(*rfit)->cycles);
    	DestroyGIFDELI(&(*rfit)->gifdeli);
    	DestroyPLCDELI(&(*rfit)->plcdeli);
        FREE(*rfit);
      }
    }
    A la sortie de cette fonction, rfit == NULL. Dans le debugger, pas à pas, tous les champs sont bien remis à NULL. Lorsque je sors de cette fonction, rfit->gif (idem pour tous les champs), le debugger m'affiche

    gif CXX0030: Error: expression cannot be evaluated
    pourquoi ?

    Maintenant, lorsque ma fonction "coeur de calcul" est appelée via une DLL (j'ai fait un autre projet qui me crée ma dll et au lieu d'appeler la fonction j'appelle la dll), le programme plante lors de la libération de la mémoire.

    Pouvez-vous m'aider s'il vous plait ? Je vous envoie qq structures. Si je comprends pour le champs rfit->gif, je comprendrais pour tout le reste.

    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
    22
    23
    24
    25
    26
    27
    28
    29
     
    typedef struct
    {
      double coeff[GIF_MAX_NBELEM];
      double ted;
      double teg;
      double etr;
      double em;
    } GIF;
     
    GIF * CreateGIF(double coeff[GIF_MAX_NBELEM],double ted,double teg,double etr,double em)
    {
      int i;
      GIF * gif=malloc(sizeof(*gif));
      if(gif == NULL) return NULL;
     
      for(i=0;i<GIF_MAX_NBELEM;i++) gif->coeff[i]=coeff[i];
      gif->ted=ted;
      gif->teg=teg;
      gif->etr=etr;
      gif->em=em;
     
      return gif;
    }
     
    void DestroyGIF(GIF ** gif)
    {
      FREE(*gif);
    }
    Merci d'avance

  2. #2
    Membre confirmé
    Inscrit en
    Juillet 2005
    Messages
    512
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 512
    Points : 641
    Points
    641
    Par défaut
    Pour liberer une zone memoire alloué avec malloc on utilise free et non pas FREE.
    (FREE connait pas !)

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 298
    Points : 886
    Points
    886
    Par défaut
    salut,

    oups, j'ai oublié de préciser ma macro

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    #define FREE(p) \
    do              \
    {               \
      free(p);      \
      p=NULL;       \
    }               \
    while(0)

  4. #4
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par salseropom Voir le message
    salut,

    oups, j'ai oublié de préciser ma macro

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    #define FREE(p) \
    do              \
    {               \
      free(p);      \
      p=NULL;       \
    }               \
    while(0)
    Ce qui est une façon compliquée d'écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    #define FREE(p) free(p), (p) = NULL
    Pas de Wi-Fi à la maison : CPL

  5. #5
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par salseropom Voir le message
    A la sortie de cette fonction, rfit == NULL. Dans le debugger, pas à pas, tous les champs sont bien remis à NULL. Lorsque je sors de cette fonction, rfit->gif <...>
    Tu cherches à déréférencer un pointeur NULL ?
    Maintenant, lorsque ma fonction "coeur de calcul" est appelée via une DLL (j'ai fait un autre projet qui me crée ma dll et au lieu d'appeler la fonction j'appelle la dll), le programme plante lors de la libération de la mémoire.

    Pouvez-vous m'aider s'il vous plait ? Je vous envoie qq structures. Si je comprends pour le champs rfit->gif, je comprendrais pour tout le reste.
    Ce code
    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
     
    #include <stdlib.h>
    #include <string.h>
     
    #define FREE(p) free(p), (p) = NULL
     
    #define GIF_MAX_NBELEM 10
     
    typedef struct
    {
       double coeff[GIF_MAX_NBELEM];
       double ted;
       double teg;
       double etr;
       double em;
    }
    GIF;
     
    GIF *CreateGIF (double coeff[GIF_MAX_NBELEM], double ted, double teg,
                    double etr, double em)
    {
     
       GIF *gif = malloc (sizeof *gif);
       if (gif != NULL)
       {
          memcpy (gif->coeff, coeff, sizeof gif->coeff);
     
          gif->ted = ted;
          gif->teg = teg;
          gif->etr = etr;
          gif->em = em;
       }
       return gif;
    }
     
    void DestroyGIF (GIF ** gif)
    {
       FREE (*gif);
    }
    est correct. Le problème est ailleurs.
    Pas de Wi-Fi à la maison : CPL

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 298
    Points : 886
    Points
    886
    Par défaut
    Re-bonjour,
    j'ai réussi (en partie) à reproduire l'erreur que j'obtiens dans un code "plus court". Je dis "en partie" car en mode Release il n'y a aucun problème mais en mode Debug j'ai comme erreur : "Debug assertion failed - file dbgheap.c line 1044".

    J'ai cette même erreur dans mon programme (qui plante aussi en mode Release).

    Dans le fichier main1.c je crée ma dll et dans le fichier main2.c j'appelle non plus la fonction DoubleToto() mais la DLL qui contient cette fonction.

    Pourquoi ai-je une telle erreur en mode Debug ? Je rappelle que je travaille sous Visual Studio C++ 6.0

    Merci d'avance

    Voici le fichier main1.c
    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
     
    #include<stdlib.h>
    #include<stdio.h>
     
    #define N 3
     
    typedef struct
    {
      double a;
      double b;
      double tab[N];
    } Toto;
     
    Toto * CreateToto(double a,double b,double * tab)
    {
      int i;
     
      Toto * toto=malloc(sizeof(*toto));
      if(toto != NULL)
      {
        toto->a=a;
    	toto->b=b;
    	for(i=0;i<N;i++) toto->tab[i]=tab[i];
      }
      return toto;
    }
     
    void DestroyToto(Toto ** toto)
    {
      free(*toto); *toto=NULL;
    }
     
    void PrintToto(Toto * toto)
    {
       int i;
       printf("%f\t%f\n",toto->a,toto->b);
       for(i=0;i<N;i++) printf("%f\t",toto->tab[i]);
       printf("\n");
    }
     
    __declspec(dllexport) Toto * DoubleToto(Toto * toto)
    {
      int i;
      Toto * toto2=malloc(sizeof(*toto2));
      if(toto2!=NULL)
      {
        toto2->a=2.*toto->a;
        toto2->b=2.*toto->b;
    	for(i=0;i<N;i++) toto2->tab[i]=toto->tab[i]*2.;
      }
      return toto2;
    }
     
     
    int main(void)
    {
      double a,b,tab[]={1.,4.,5};
      Toto * toto=NULL, * toto2=NULL;
      a=1.;
      b=2.;
     
      toto=CreateToto(a,b,tab);
      PrintToto(toto);
      toto2=DoubleToto(toto);
      PrintToto(toto2);
      DestroyToto(&toto);
      DestroyToto(&toto2);
     
      return 0;
    }
    et voici le fichier main2.c qui appelle la dll

    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
     
    #include<stdlib.h>
    #include<stdio.h>
     
    #define N 3
     
    typedef struct
    {
      double a;
      double b;
      double tab[N];
    } Toto;
     
    Toto * CreateToto(double a,double b,double * tab)
    {
      int i;
     
      Toto * toto=malloc(sizeof(*toto));
      if(toto != NULL)
      {
        toto->a=a;
    	toto->b=b;
    	for(i=0;i<N;i++) toto->tab[i]=tab[i];
      }
      return toto;
    }
     
    void DestroyToto(Toto ** toto)
    {
      free(*toto); *toto=NULL;
    }
     
    void PrintToto(Toto * toto)
    {
       int i;
       printf("%f\t%f\n",toto->a,toto->b);
       for(i=0;i<N;i++) printf("%f\t",toto->tab[i]);
       printf("\n");
    }
     
    extern Toto * __cdecl DoubleToto(Toto *);
     
     
    int main(void)
    {
      double a,b,tab[]={1.,4.,5};
      Toto * toto=NULL, * toto2=NULL;
      a=1.;
      b=2.;
     
      toto=CreateToto(a,b,tab);
      PrintToto(toto);
      toto2=DoubleToto(toto);
      PrintToto(toto2);
      DestroyToto(&toto);
      DestroyToto(&toto2);
     
      return 0;
    }

  7. #7
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par salseropom Voir le message
    Dans le fichier main1.c je crée ma dll et dans le fichier main2.c j'appelle non plus la fonction DoubleToto() mais la DLL qui contient cette fonction.
    Le fichier main1.c n'est pas un fichier de DLL correct. Il n'y a pas de main() dans une DLL. Il y'a par contre un point d'entrée obligatoire à fournir (DllMain()). Lire la doc de MSDN.
    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
    // a sample exported function
    void DLL_EXPORT SomeFunction(const LPCSTR sometext)
    {
        MessageBoxA(0, sometext, "DLL Message", MB_OK | MB_ICONINFORMATION);
    }
     
    BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
    {
        switch (fdwReason)
        {
            case DLL_PROCESS_ATTACH:
                // attach to process
                // return FALSE to fail DLL load
                break;
     
            case DLL_PROCESS_DETACH:
                // detach from process
                break;
     
            case DLL_THREAD_ATTACH:
                // attach to thread
                break;
     
            case DLL_THREAD_DETACH:
                // detach from thread
                break;
        }
        return TRUE; // succesful
    }
    D'autre part attention au vocabulaire. on n'"appelle" pas une DLL. On appelle éventuellement une fonction de la DLL. Encore faut-il que le lien dynamique ait été réalisé. As-tu lié le .lib de ta DLL a ton application ?
    Pas de Wi-Fi à la maison : CPL

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 298
    Points : 886
    Points
    886
    Par défaut
    Citation Envoyé par Emmanuel Delahaye Voir le message
    Le fichier main1.c n'est pas un fichier de DLL correct. Il n'y a pas de main() dans une DLL. Il y'a par contre 2 points d'entrée obligatoires à fournir. Lire la doc de MSDN.

    D'autre part attention au vocabulaire. on n'"appelle" pas une DLL. On appelle éventuellement une fonction de la DLL. Encore faut-il que le lien dynamique ait été réalisé. As-tu lié le .lib de ta DLL a ton application ?
    oui, je me suis planté dans ce post. Dans mon projet visual je n'ai pas de main pour faire ma DLL.
    Sinon, j'ai bien réalisé le lien dynamique de ma DLL. Dans mon projet où j'appelle une fonction de ma DLL, tout le programme tourne. Ce n'est qu'à la fin du main (donc je suis sorti de la fonction appelée dans la DLL), lors de la libération mémoire, que ça plante...

    En revanche, en mode exécutable, la libération de la mémoire s'effectue correctement. Bien entendu, c'est le même code pour libérer la mémoire.

    Je me renseigne sur le point d'entrée de la DLL.

  9. #9
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Citation Envoyé par salseropom Voir le message
    en mode Debug j'ai comme erreur : "Debug assertion failed - file dbgheap.c line 1044".

    Ce qui a été alloué par un module doit être libéré par le même module. Une transgression de cette règle est sûrement la source de ton erreur.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  10. #10
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 298
    Points : 886
    Points
    886
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Ce qui a été alloué par un module doit être libéré par le même module. Un transgression de cette règle est sûrement la source de ton erreur.

    Effectivement, cela peut répondre à mon problème.

    voici un organigramme de mon code :

    int main(void)
    {
    1) je lis mes inputs contenues dans différents fichiers texte
    2) coeur de calcul : ici j'appelle une fonction de ma DLL. Cette fonction appelle d'autres fonctions qui ne sont pas dans ma DLL. Dans le coeur de calcul j'alloue de la mémoire
    3) post-traitement : j'écris sur le disque dur tout plein de résultats
    4) je libère la mémoire (allouée lors de la lecture des inputs et dans la fonction appelée par la DLL). C'est dans cette partie qu'apparait le problème

    return 0;
    }
    Mais cela me cause un autre soucis : si je comprends bien, toute la mémoire allouée lors de l'exécution du coeur de calcul (qui appelle une fonction de ma DLL et cette fonction appelle plein d'autres fonctions qui ne sont pas dans la DLL) doit être libérée à la sortie du coeur de calcul.

    Donc comment écrire sur le disque dur mes sorties (j'ai un peu peur de poser une question bête...) si j'ai libérée ma mémoire. Je dois avoir un problème de conception alors. En tous les cas, l'organigramme doit être respecté :

    1) pré-traitement
    2) traitement : appel du coeur de calcul
    3) écriture des résultats
    4) libération de la mémoire

    et je dois fournir mon coeur de calcul sous forme de DLL

    Merci encore de votre aide

  11. #11
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Citation Envoyé par salseropom Voir le message
    si je comprends bien, toute la mémoire allouée lors de l'exécution du coeur de calcul (qui appelle une fonction de ma DLL et cette fonction appelle plein d'autres fonctions qui ne sont pas dans la DLL) doit être libérée à la sortie du coeur de calcul.
    Ou à tout moment, du moment que c'est une fonction de la DLL qui le fait.
    Tu peux même exporter une fonction de la DLL exprès pour ça...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  12. #12
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 298
    Points : 886
    Points
    886
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Ou à tout moment, du moment que c'est une fonction de la DLL qui le fait.
    Tu peux même exporter une fonction de la DLL exprès pour ça...
    Salut, c'est ce que je viens de faire. j'ai inclus ma fonction DestroyMemory() dans la DLL.

    Merci beaucoup de votre aide !

    En revanche, je n'ai pas bien compris ce que disais Emmanuel quant aux 2 points d'accroche... je vais continuer à chercher

  13. #13
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par salseropom Voir le message
    En revanche, je n'ai pas bien compris ce que disais Emmanuel quant aux 2 points d'accroche... je vais continuer à chercher
    Un point. Euh, tu as relu mon post ?
    Pas de Wi-Fi à la maison : CPL

  14. #14
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 298
    Points : 886
    Points
    886
    Par défaut
    Citation Envoyé par Emmanuel Delahaye Voir le message
    Un point. Euh, tu as relu mon post ?
    dans mon code je fais ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    __declspec(dllexport) int Ajuste_NC(int NombreFichiers, donnees **data,int **tabErreur,ResultatFit * rfit)
    {
     /* code */
    }
     
    __declspec(dllexport) void DestroyResultatFit(ResultatFit * rfit)
    {
     /* code */
    }
    Ces 2 fonctions créent ma DLL. Dans ton post, tu as écrit

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    void DLL_EXPORT SomeFunction(const LPCSTR sometext)
    quelle est la différence (autre que syntaxique) entre ce que je fais et ce que tu as écrit dans ton code ? Tu as sûrement remarqué que c'est la 1e fois que je fais une DLL...

    Merci encore

  15. #15
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par salseropom Voir le message
    dans mon code je fais ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    __declspec(dllexport) int Ajuste_NC(int NombreFichiers, donnees **data,int **tabErreur,ResultatFit * rfit)
    {
     /* code */
    }
     
    __declspec(dllexport) void DestroyResultatFit(ResultatFit * rfit)
    {
     /* code */
    }
    Ces 2 fonctions créent ma DLL. Dans ton post, tu as écrit

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    void DLL_EXPORT SomeFunction(const LPCSTR sometext)
    quelle est la différence (autre que syntaxique) entre ce que je fais et ce que tu as écrit dans ton code ? Tu as sûrement remarqué que c'est la 1e fois que je fais une DLL...

    Merci encore
    Je ne connais pas les détails par coeur (lire la doc), mais c'est le code que propose Code::Blocks par défaut et qui compile et fonctionne parfaitement.

    (il manque un .h qu'ils appellent très mal, 'main.h' et que j'ai renommé test_dll.h)
    J'ai un peu remanié :
    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
    #ifndef H_ED_TEST_DLL_20080903092301
    #define H_ED_TEST_DLL_20080903092301
     
    #ifdef __cplusplus
    extern "C"
    {
    #endif
     
    #include <windows.h>
     
    /*  To use this exported function of dll, include this header
     *  in your project.
     */
     
    #ifdef BUILD_DLL
    #define DLL_EXPORT __declspec(dllexport)
    #else
    #define DLL_EXPORT __declspec(dllimport)
    #endif
     
          void DLL_EXPORT SomeFunction (const LPCSTR sometext);
     
    #ifdef __cplusplus
    }
    #endif
     
    #endif                          /* guard */
     
    /* Guards added by GUARD (c) ED 2000-2005 Jan 17 2005 Ver. 1.7 */
    Je crois que le header parle de lui même. La macro DLL_EXPORT est une création de Code::Blocks.

    Dans ta DLL, il n'y a pas de point d'entrée. Bon, c'est peut être pas obligatoire. Il se peut que ça fonctionne sans...

    Voilà l'exemple qui fonctionne :
    DLL :
    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
     
    #include "test_dll.h"
     
    #include <stdio.h>
     
    #define BUILD_STAMP "built "__DATE__" "__TIME__
     
    /* a sample exported function */
    void DLL_EXPORT SomeFunction (const LPCSTR sometext)
    {
       MessageBoxA (0, sometext, "DLL Message", MB_OK | MB_ICONINFORMATION);
    }
     
    BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
    {
       switch (fdwReason)
       {
       case DLL_PROCESS_ATTACH:
          /* attach to process */
          /* return FALSE to fail DLL load */
          printf("Attaching test-dll " BUILD_STAMP"\n");
          break;
     
       case DLL_PROCESS_DETACH:
          /* detach from process */
          printf("detaching test-dll " BUILD_STAMP"\n");
          break;
     
       case DLL_THREAD_ATTACH:
          /* attach to thread */
          break;
     
       case DLL_THREAD_DETACH:
          /* detach from thread */
          break;
       }
       return TRUE;                 /* succesful */
    }
    Application de test :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    #include "../test_dll.h"
     
    int main (void)
    {
       const LPCSTR sometext = "Hello world";
     
       SomeFunction (sometext);
     
       return 0;
    }
    En mode console, ça donne ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Attaching test-dll built Sep  3 2008 09:29:55
    detaching test-dll built Sep  3 2008 09:29:55
     
    Process returned 0 (0x0)   execution time : 6.853 s
    Press any key to continue.
    avec en prime un loli petit 'message box' avec "Hello world".
    Pas de Wi-Fi à la maison : CPL

  16. #16
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Tu dois renommer les deux macros en question pour qu'elles soient uniques:
    http://www.developpez.net/forums/m1641642-6/
    Et n'oublie pas de le faire aussi dans les options du projet de la DLL...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  17. #17
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Tu dois renommer les deux macros en question pour qu'elles soient uniques:
    http://www.developpez.net/forums/m1641642-6/
    Et n'oublie pas de le faire aussi dans les options du projet de la DLL...
    Tout cela a l'air d'être géré automatiquement par Code::Blocks, ce que je trouve bien pratique..
    Pas de Wi-Fi à la maison : CPL

  18. #18
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 298
    Points : 886
    Points
    886
    Par défaut
    OK,
    j'ai modifié mon code en ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    int __declspec(dllexport) Ajuste_NC(int NombreFichiers, donnees **data,int **tabErreur,ResultatFit * rfit)
    {
    /* code */
    }
     
    void __declspec(dllexport) DestroyResultatFit(ResultatFit * rfit)
    {
    /* code */
    }
    j'espère avoir bien compris ton précédent post.

  19. #19
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 298
    Points : 886
    Points
    886
    Par défaut
    oups, je n'avais pas vu la réponse de Médinoc

  20. #20
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Citation Envoyé par Emmanuel Delahaye Voir le message
    Tout cela a l'air d'être géré automatiquement par Code::Blocks, ce que je trouve bien pratique..
    Ça fait un moment que je n'ai pas regardé avec C::B, et je ne l'ai pas sous la main pour l'instant.
    Mais sous Dev-C++, les macros avaient toujours le même nom, au lieu d'être uniques.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [MFC] Problèmes d'inclusion d'une DLL
    Par CaptnB dans le forum MFC
    Réponses: 1
    Dernier message: 12/05/2006, 18h01
  2. [VB] Problème de chargement d'une DLL
    Par Elijha dans le forum Windows Forms
    Réponses: 3
    Dernier message: 10/05/2006, 09h24
  3. Réponses: 2
    Dernier message: 10/02/2006, 14h46
  4. Problème de création d'une dll...
    Par adrien954 dans le forum C++Builder
    Réponses: 4
    Dernier message: 21/10/2005, 10h46
  5. Problème mémoire avec une dll par chargement dynamique
    Par widze19 dans le forum C++Builder
    Réponses: 6
    Dernier message: 15/12/2003, 13h20

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