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 :

Dll avec structure dynamique en c pour vb


Sujet :

C

  1. #1
    sas
    sas est déconnecté
    Membre éprouvé

    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 54
    Points : 1 257
    Points
    1 257
    Par défaut Dll avec structure dynamique en c pour vb
    je développe une dll en c (avec visual C++) utilisable sous vb mais je rencontre quelques difficultés, je vais essayer d'être le plus clair possible :

    dans mon source c j'utilise une structure à allocation dynamique pour placer des infos d'un fichier en accès binaire(style carnet d'adresse)

    d'abord le code en c :

    la structure ressemble à ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    struct FICHE
    {
        long ID;
        char *Nom;
        char *Prenom;
        char *Adresse;
        int    Age;
        .
        .
    }
    ma fonction que j'exporte pour vb est la suivante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int _stdcall ReadFiche(char *FileName, FICHE *Personne)
    {
        FILE *pFile;
        .
        . ici je vous passe les modalitées d'ouverture du fichier
     
        Personne = ReadData(pFile,  Personne->ID);
     
        return 0;
    }
    ReadData est une routine qui retourne un pointeur sur une structure FICHE générée grace à l'ID de la fiche,
    sa déclaration est la suivante : FICHE *ReadData(FILE *pFile, long ID)


    sous vb maintenant g déclarer ma fonction ReadFiche comme ça:
    Private Declare Function ReadFiche Lib "fiche.dll" (ByVal szFile As String, ByRef Personne As FICHE) As Long

    et dans une sub de mon source vb je tente de lire une fiche avec
    Sub ...
    Dim Personne as FICHE
    Dim iRet as long

    Personne.Id = 183
    iRet = ReadFiche(MonFichier, Personne)
    End Sub

    je place l'ID d'une fiche à lire (dans l'exemple 183) dans la structure Personne en souhaitant qu'à la fin de l'exécution de la fonction ReadFiche la fiche soit remplie.
    mais voilà le début des problèmes :

    sous vb en mode debug, au retour de la fonction il ya juste Personne.Id = 183 le reste des champs sont vides...
    je passe donc un coup de debug sous vc++ et surprise :les fonctions ReadFiche et ReadData se sont bien dérouler au moment du return 0 de ReadFiche, 'Personne' est remplie correctement mais l'adresse du pointeur a changé donc "normal"??? qu'aucune info soit présente dans la structure Personne sous vb, elle pointe ailleurs (pour ma part rien que ça c pas logique)

    alors voici ma question : comment je fait pour que la structure Personne soit bien remplie ??????

    noter qu'avant de poster g fait ça comme variante mais ça marche pas :

    passer par une fiche temporaire puis, pointer Personne sur cette nouvelle fiche comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    int _stdcall ReadFiche(char *FileName, FICHE *Personne)
    {
        FILE *pFile;
        FICHE *tmp_Personne
        .
        . 
        tmp_Personne = ReadData(pFile,  Personne->ID);
     
        memmove(Personne, tmp_Personne, sizeof(*tmp_Personne));
     
        return 0;
    }
    la fonction s'éxécute correctement (Personne est bien rempli) mais apparement quand il retourne sous vb ya un bug :
    j'ai un message d'erreur du style User breakpoint called from code at 0x.....
    et dans la fenetre debug de vc++ il y a :
    HEAP[Projet1.exe]: Invalid Address specified to RtlSizeHeap( 00140000, 00DB1E5C )

    g tenter aussi en changeant ma fonction pour qu'elle devienne comme ça :
    FICHE *_stdcall ReadFiche(char *FileName, long ID)
    mais la un autre prob est survenu les paramètres FileName et ID sont vides....? heu je ne vois pas le 'pourquoi' de ce bug.

    merci d'avoir pris le temps de lire jusqu'au bout.

  2. #2
    Bob
    Bob est déconnecté
    Membre éclairé
    Avatar de Bob
    Inscrit en
    Mars 2002
    Messages
    115
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 115
    Points : 866
    Points
    866
    Par défaut
    A mon avis le pb vient d'un buffer overflow au niveau de tes fonctions ReadData() et ReadFiche().
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    struct FICHE
    {
    long ID;
    char *Nom;
    char *Prenom;
    char *Adresse;
    int Age;
    .
    .
    }
    Ici tu ne declare que des pointeurs. Tu es sur que tu alloue assez de memoire sur tes pointeurs ? Parce que si l'adresse des pointeurs change c'est que tu ecrase en copiant des donnees.
    Bob, Rédacteur C/C++ & PHP
    http://bob.developpez.com/

  3. #3
    sas
    sas est déconnecté
    Membre éprouvé

    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 54
    Points : 1 257
    Points
    1 257
    Par défaut
    j'ai vérifié mais je n'en vois pas
    mais pourrais tu m'expliquer pour quoi quand je fait comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int _stdcall ReadFiche(char *FileName, FICHE *Personne)
    {
        FILE *pFile;
        .
        . ici je vous passe les modalitées d'ouverture du fichier
     
        Personne = ReadData(pFile,  Personne->ID);
     
        return 0;
    }
    sous vb tous les champs de ma structures sont vides alors que dans la dll tout est rempli je ne comprends pas de plus avec cette methode il n'y a aucun bug...

    au passage comment on fait en vb pour récuper l'adresse de mon Personne As FICHE ???

    pour l'allocation dans ReadData je procède comme ça :

    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
    FICHE *ReadData(FILE *pFile, long ID)
    {
     
    	FICHE *fp = (FICHE *)malloc(sizeof(FICHE)+1);
     
    	/*
    		je passe le code pour recupérer la taille de chaque chaine.
     
    		ensuite pour placer les chaines dans les char * de la structure je fait :
    	*/
     
     
    	if (wNomSize > 0)	
    	{
    		fp->Nom = (char *)malloc(wNomSize+1);
    		fread(fp->Nom, 1 ,wNomSize, pFile); //	
    	}
     
    	if (wPrenomSize > 0)	
    	{
    		fp->Prenom = (char *)malloc((wPrenomSize+1);
    		fread(fp->Prenom, 1 ,(wPrenomSize, pFile); //	
    	}
     
    	if (wAdresseSize > 0)	
    	{
    		fp->Adresse = (char *)malloc(wAdresseSize+1);
    		fread(fp->Adresse, 1 ,wAdresseSize, pFile); //	
    	}
     
     
    	et ainsi de suite...
     
    	return fp;
    }

  4. #4
    Bob
    Bob est déconnecté
    Membre éclairé
    Avatar de Bob
    Inscrit en
    Mars 2002
    Messages
    115
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 115
    Points : 866
    Points
    866
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    FICHE *fp = (FICHE *)malloc(sizeof(FICHE)+1);
    Voila ce qui pose pb.

    si tu fais un sizeof(FICHE) tu va seulement obtenir la taille des pointeurs. Tu dois en plus allouer de la memoire pour stocker tes chaines de caractre.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    FICHE *fp = (FICHE *)malloc(sizeof(FICHE)+1); 
    fp->Nom=malloc(TailleDeChaine+1);
    ....
    Et apres ne pas oublier de desalouer la memoire.
    Bob, Rédacteur C/C++ & PHP
    http://bob.developpez.com/

  5. #5
    sas
    sas est déconnecté
    Membre éprouvé

    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 54
    Points : 1 257
    Points
    1 257
    Par défaut
    c'est moi ou tu ne lis pas mon message en entier????

    regarde bien ma fonction ReadData
    au debut de ma fonction j'alloue de la mémoire pour la structure de pointeurs comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    FICHE *fp = (FICHE *)malloc(sizeof(FICHE)+1); 
     
    ensuite j'alloue pour chaque chaine avec cette methode :
    if (wNomSize > 0) 
    { 
       fp->Nom = (char *)malloc(wNomSize+1); 
       fread(fp->Nom, 1 ,wNomSize, pFile); // 
    }
    ou wNomSize est la taille de la chaine

  6. #6
    Bob
    Bob est déconnecté
    Membre éclairé
    Avatar de Bob
    Inscrit en
    Mars 2002
    Messages
    115
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 115
    Points : 866
    Points
    866
    Par défaut
    Argh desole. J'avoue que j'ai un peu lu le message en diagonale.
    Et euh juste une question, pourquoi sizeof(FICHE)+1, pourquoi le +1 ?
    Tu as essaye de savoir a partir de quel moment le pointeur etait modifie (tu as dit dans ton premier message que le pointeur etait modifie).
    Bob, Rédacteur C/C++ & PHP
    http://bob.developpez.com/

  7. #7
    sas
    sas est déconnecté
    Membre éprouvé

    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 54
    Points : 1 257
    Points
    1 257
    Par défaut
    Et euh juste une question, pkoi sizeof(FICHE)+1, pkoi le +1 ?
    j'avoue que je sais pas pourquoi j'ai mis un +1, peut-être à force dans mettre pour mes char * , je l'ai virer mais rien n'est changé...

    Tu as essaye de savoir a partir de kel moment le pointeur etait modifie
    en fait dans ReadFiche le pointeur qui est passer en paramètre est initialisé a partir de vb avec : Dim Personne as FICHE

    juste avant de faire Personne = ReadData(pFile, Personne->ID);
    il pointe a une certaine adresse, une fois l'exécution de la fonction ReadData effectué il pointe ailleurs (en fait il pointe sur le FICHE *fd de ReadData) au final (sous vb) après l'éxécution de ReadFiche le Personne est vide , j'aimerais bien comprendre le pourquoi du comment??

    j'espère de ne pas être fouilli dans mes explications

  8. #8
    Bob
    Bob est déconnecté
    Membre éclairé
    Avatar de Bob
    Inscrit en
    Mars 2002
    Messages
    115
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 115
    Points : 866
    Points
    866
    Par défaut
    Le bp est ici j pense :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int _stdcall ReadFiche(char *FileName, FICHE *Personne)
    {
        FILE *pFile;
        .
        . ici je vous passe les modalitées d'ouverture du fichier
     
        Personne = ReadData(pFile,  Personne->ID);
     
        return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Personne = ReadData(pFile,  Personne->ID);
    Ce n'est pas correct. Tu ne peux pas assigner une valeur a Personne comme ca. Tu devrais faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int _stdcall ReadFiche(char *FileName, FICHE **Personne)
    {
        FILE *pFile;
        .
        . ici je vous passe les modalitées d'ouverture du fichier
     
        *Personne = ReadData(pFile,  Personne->ID);
     
        return 0;
    }
    Et la j pense que ca marcherait
    Bob, Rédacteur C/C++ & PHP
    http://bob.developpez.com/

  9. #9
    sas
    sas est déconnecté
    Membre éprouvé

    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 54
    Points : 1 257
    Points
    1 257
    Par défaut
    effectivement c'est plus censé, j'ai essayer cette méthode il n'y a plus d bug de breakpoint. Par contre sous vb ma structure n'est toujours pas rempli et j'ai juste mon Personne.ID = *Personne, mais la je crois que je devrais plutôt chercher du coté de vb.

    une petite question à titre informatif, puique dans ma fonction ReadFiche j'ai Personne qui est devenu un pointeur de pointeur, j'accède comment aux données ??
    sous visual c++ dans la fonction ReadFiche Personne->ID provoque l'erreur suivante :
    error C2227: left of '->ID' must point to class/struct/union

  10. #10
    Bob
    Bob est déconnecté
    Membre éclairé
    Avatar de Bob
    Inscrit en
    Mars 2002
    Messages
    115
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 115
    Points : 866
    Points
    866
    Bob, Rédacteur C/C++ & PHP
    http://bob.developpez.com/

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    124
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Mars 2004
    Messages : 124
    Points : 95
    Points
    95
    Par défaut
    je peux savoir dans quel tuto on trouve "->" parce que j'aimerai bien savoir ce que c'est exactement !
    Mieux vaut rien dire que de se taire !

  12. #12
    sas
    sas est déconnecté
    Membre éprouvé

    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 54
    Points : 1 257
    Points
    1 257
    Par défaut
    je peux savoir dans quel tuto on trouve "->" parce que j'aimerai bien savoir ce que c'est exactement !
    le -> permet de désigner un élément quand on utilise un pointeur vers une structure, dans le cas de ma structure :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
        //tu peux faire :
         FICHE Personne;  
         // en accèdant aux éléments comme ceci
         Personne.ID = 1;
     
         // ou sinon :
         FICHE *Personne;
         // mais cette fois tu y accède par
         Personne->ID = 1;
    tu trouveras surement des tutos avec google en tapant pointeur de structure

    Bob -> merci pour ton aide!!

    une suite à ce problème se trouve ici

  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 Sun3clipse
    je peux savoir dans quel tuto on trouve "->" parce que j'aimerai bien savoir ce que c'est exactement !
    Dans tout livre de C qui se respecte, comme le Kernighan & Ritchie édition 2, par exemple.
    http://www.eyrolles.com/Informatique/Livre/9782100051168/
    Pas de Wi-Fi à la maison : CPL

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 14/03/2007, 02h38
  2. Réponses: 13
    Dernier message: 20/06/2005, 14h13
  3. [débutant][Conception] Structure dynamique avec Java
    Par blaiseac dans le forum Général Java
    Réponses: 5
    Dernier message: 18/11/2004, 23h00
  4. Conf DNS pour serveur mail avec IP dynamique ?
    Par ovh dans le forum Réseau
    Réponses: 9
    Dernier message: 14/06/2004, 22h55
  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