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 :

Ces chaînes qui se déchainent.


Sujet :

C

  1. #1
    Membre expérimenté Avatar de peijnoob
    Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    279
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 279
    Par défaut Ces chaînes qui se déchainent.
    Bonjour à tous,

    J'ai un petit souci de chaines qui me fait lamentablement planter mon prog.

    C'est un peu en rapport avec un sujet que j'ai posté il y a peu de temps, mais le problème n'est pas tout à fait le même.

    Voici le bout de code qui me pose problème :

    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
     
        if (strcmp(callBackMessage,"\0"))
        {
            tempBuff = (char *)malloc(sizeof(callBackMessage) + 3);
            if (tempBuff == NULL) MessageBox (0, "Pb malloc !!", "Erreur", MB_ICONINFORMATION);
            else{
            MessageBox (0, callBackMessage, "Test", MB_ICONINFORMATION);
            sprintf(tempBuff, "1K%s", callBackMessage);
            strcpy(lpszReceiveBuff, tempBuff);
            buffSize = strlen(tempBuff);
            free(tempBuff);
            return buffSize;
            }
        }
        return 0;
    La 2e MessageBox, c'est pour vérifier le contenu de callBackMessage. Et il est bon.

    Le problème se situe au moment du sprintf. L'appli de test, avec laquelle je fais appel à la fonction de la DLL plante lamentablement, sans même un message d'erreur.

    Pourtant, l'allocation mémoire est OK, callBackMessage est OK. Je vois vraiment pas pourquoi ça veux pas marcher.

    Au niveau déclarations :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    char * callBackMessage;
    [...]
    char * tempBuff;
    int buffSize;
    callBackMessage est une chaine initialisée par une fonction callBack d'une API.

    Si quelqu'un voit d'où vient le problème Je galère vraiment là, je suis loin d'être un expert en C.

  2. #2
    Membre émérite Avatar de homeostasie
    Homme Profil pro
    Inscrit en
    Mai 2005
    Messages
    939
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 939
    Par défaut
    Remarque sur la dimension de l'espace alloué:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tempBuff = (char *)malloc(sizeof(callBackMessage) + 3);
    Le transtypage en char* est inutile et le sizeof retourne la taille du pointeur...alors que dans ton cas il faut retourner la taille d'un char.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tempBuff = malloc(sizeof(*callBackMessage) + 3);

  3. #3
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    Salut !


    Ton problème doit surement se situer dans l'allocation:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    tempBuff = (char *)malloc(sizeof(callBackMessage) + 3);
    En fait, tu utilise sizeof pour la taille de la chaîne alors qu'il retourne la taille de l'objet ... il faut que tu détermine la taille de la chaîne avec strlen !
    Attention toutes fois à strlen, elle te retourne la taille de la chaîne mais sans le zéro de fin de chaîne !

    Après tout dépend de ce que tu veux faire, juste avoir la taille d'un char ou allouer d'après la taille de la chaîne contenue dans callBaclMessage ?


    PS: Le cast n'est pas nécessaire en C dans ce cas de figure !
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  4. #4
    Membre expérimenté Avatar de peijnoob
    Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    279
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 279
    Par défaut
    Oki, le problème vient sûrement de l'allocation mémoire alors, oui

    Mon but est de créer un buffer pour copier callBackMessage en y ajoutant quelques caractères au début (et à la fin aussi d'ailleurs ^^)

    Vais essayer en changeant la ligne de malloc, merci

  5. #5
    Membre expérimenté Avatar de peijnoob
    Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    279
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 279
    Par défaut
    Yes, après application de vos conseils, ça marche nickel, merci

    PS: Le cast n'est pas nécessaire en C dans ce cas de figure !
    Need explications sur ce point Dans quels cas le cast est-il nécessaire ?? (désolé, je suis pas encore expert, je lis en ce moment les cours présents sur le site, mais j'ai pas encore tout assimilé)

    Merci encore

  6. #6
    Membre éprouvé
    Avatar de granquet
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    1 201
    Détails du profil
    Informations personnelles :
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 201
    Par défaut
    Citation Envoyé par peijnoob
    Need explications sur ce point Dans quels cas le cast est-il nécessaire ??
    quand tu programme en C++.
    en C les conversions (void *) -> (type *) se font implicitement.

    http://emmanuel-delahaye.developpez....tes.htm#malloc

  7. #7
    Membre expérimenté Avatar de peijnoob
    Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    279
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 279
    Par défaut
    Bonjour à tous

    J'ai encore un petit souci et je n'ai pas voulu faire un nouveau post.

    Dans une autre fonction, je dois écrire une chaine à une adresse qui m'est passée en paramètre.

    Voici le prototype de ma fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    DLLIMPORT int __stdcall getChaine6 (int channel, BYTE bufferAdr);
    Ici, le paramètre est de type BYTE donc. Il représente l'adresse mémoire du buffer dans lequel je dois écrire. Me demandez pas pourquoi il n'est pas de type char *, je n'en sais moi même rien (je dois réécrire une dll dont je n'ai pas le code).

    La chaine est de taille fixe et fait 6 caractères.

    Mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    DLLIMPORT int __stdcall getChaine6 (int channel, BYTE bufferAdr)
    {
     
        strcpy((char *)bufferAdr, "AZERTY");
     
        return 1;
    }
    Ma démarche a été la suivante : si bufferAdr est l'adresse de ma zone mémoire, il doit être possible de l'interpréter comme un pointeur sur cette zone mémoire. Un char * est un pointeur aussi.. Donc, je me suis dit que je pouvais le transtyper.

    Je n'ai pas besoin d'allouer le buffer, il existe déjà (il est créé par l'application qui appelle la dll).

    Mais pareil, lamentable crash de l'application, apparemment une fuite mémoire..

    J'ai regardé plusieurs cours sur les pointeurs mais je n'arrive décidément pas à bien assimiler le concept.

    Merci d'avance pour vos réponses

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par peijnoob
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    DLLIMPORT int __stdcall getChaine6 (int channel, BYTE bufferAdr);
    Ici, le paramètre est de type BYTE donc. Il représente l'adresse mémoire du buffer dans lequel je dois écrire.
    Ceci est extrèmement suspect. Tant que je n'aurais pas vu la définition de BYTE, telle que la voit ton compilateur je n'irais pas plus loin.

  9. #9
    Membre expérimenté Avatar de peijnoob
    Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    279
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 279
    Par défaut
    Je code avec Code::Blocks, le compilateur est celui par défaut, GCC donc.

    La définition du BYTE, je ne sais même pas où je peux la trouver ^^

    Après, qu'est-ce que tu trouves de suspect ?? Enfin, ici, j'invente rien, la définition de la fonction est celle là, et je peux pas faire autrement.. Si je le pouvais, je le ferais, je t'assures

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 400
    Par défaut
    +1 Emmanuel.

    Quant à la définition DLLIMPORT, je me doute bien de ce qu'il y a dedans, mais c'est un mauvais usage des __declspec(dllimport)/__declspec(dllexport)...

    PS: Tu es absolument sûr que le type est bien BYTE, et non pas BYTE*, PBYTE ou LPBYTE ?
    Car ce qui est certain, c'est qu'on ne peut pas mettre une adresse dans un BYTE:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    //WinDef.h du 14/04/2005, ligne 153
    typedef unsigned char BYTE;
    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.

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par peijnoob
    Je code avec Code::Blocks, le compilateur est celui par défaut, GCC donc.

    La définition du BYTE, je ne sais même pas où je peux la trouver ^^

    Après, qu'est-ce que tu trouves de suspect ?? Enfin, ici, j'invente rien, la définition de la fonction est celle là, et je peux pas faire autrement.. Si je le pouvais, je le ferais, je t'assures
    BYTE n'est pas un type standard du C.

    Certaines implémentations le définissent comme unsigned char, ce qui ne convient évidemment pas pour une adresse.

    Je penche pour BYTE *.

  12. #12
    Membre expérimenté Avatar de peijnoob
    Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    279
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 279
    Par défaut
    Oups Médinoc, je n'avais pas vu ta réponse.

    En effet, en changeant mon paramètre en BYTE *, ça a l'air de fonctionner..

    En fait, je vais même carrément pourvoir le changer en LPSTR... En effet, je viens de me rendre compte d'un truc.. Les définitions présentes dans la doc de la dll que je dois remplacer sont complètement fausses !!!

    En regardant de plus près le header fourni avec la DLL, j'ai les bonnes définitions (ça va un petit peu m'aider xD)

    Mea culpa, désolé de vous avoir fait perdre de votre temps

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par peijnoob
    Les définitions présentes dans la doc de la dll que je dois remplacer sont complètement fausses !!!

    En regardant de plus près le header fourni avec la DLL, j'ai les bonnes définitions (ça va un petit peu m'aider xD)
    Une fois de plus, le viel adage est vérifié :

    "The only true documentation is the code itself"

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

Discussions similaires

  1. ces pointeurs qui me hantent
    Par mesrine dans le forum Débuter
    Réponses: 8
    Dernier message: 12/02/2009, 17h25
  2. [RegEx] Je recherche une chaîne qui ne contient pas une certaine chaîne
    Par johann51 dans le forum Langage
    Réponses: 5
    Dernier message: 19/03/2008, 17h42
  3. Réponses: 3
    Dernier message: 20/02/2007, 16h48
  4. Extraîre une chaîne qui est entre deux chaînes.
    Par Horrigan dans le forum Langage
    Réponses: 5
    Dernier message: 01/09/2006, 20h01
  5. [MFC] Ces fenêtres qui ne s'affichent pas..
    Par Davide dans le forum MFC
    Réponses: 3
    Dernier message: 19/11/2003, 12h30

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