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 de compilation avec Code::Blocks et Visual Studio


Sujet :

C

  1. #1
    Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2015
    Messages
    75
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 31
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mars 2015
    Messages : 75
    Points : 59
    Points
    59
    Par défaut Problème de compilation avec Code::Blocks et Visual Studio
    Bonjour tout le monde, oui c'est encore moi !!

    J'ai besoin de vos aides SVP. Je ne sait pas si je suis dans la bonne section ou je dois me diriger vers le forum d'EDI.

    En fait, je suis entrain de développer un programme en C qui se communique avec une carte électrique sur le port UART pour récupérer le contenu de ces registres, qui seront par la suite traitées et stockées dans une base de données. J'étais sur Code::blocks et j'ai presque finalisé l'écriture et la lecture sur la carte.
    Sauf que je me suis trouvée obligée de changer l'EDI vers Visual Studio pour concevoir une IHM. et c'est ma première fois que je travaille sur ce EDI.


    J'ai copié mon code qui marchait très bien avec Code::Blocks, quand je build, la lecture plante. Et je n'arrive pas à comprendre pourquoi.


    Voici le code de lecture d'un seul registre.

    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
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
     
    /*************************************
    pour utiliser printf et sprintf correctement
    *************************************** */
    #define _CRT_SECURE_NO_WARNINGS
     
    /*******************************
    Déclaration des includes 
    ***************************** */
    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>
    #include <string.h>
    #include <malloc.h>
     
    /* *******************************
    Fonctions du modules
    ******************************* */
     
     
    #include "Struct_TrameSending.h"
    #include"Struct_Conf.h"
    #include "DumpHex.h"
    #include "Ecriture.h"
    #include "Lecture.h"
    #include"Str_To_uint32.h"
    #include "Jeu_Octets.h"
    /* *******************************
    Fonctions de conversion
    ******************************* */
     
     
    #include "V_INST.h"
     
    /* *************************************
    Définition des constantes
    ************************************* */
    #define MAX_WAIT_READ  500   // timeout de 5000ms
    #define TX_TAILLE 5
    #define RX_TAILLE 5
    /* *************************************
    Définition des vitesses de communication
    ************************************** */
    #define V9600 9600
    #define V115200 115200
     
    /* *************************************
    Définition de nombre de bits
    ************************************** */
    #define BITS_7 7
    #define BITS_8 8
     
     
    int main(void)
    {
        DCB dcb; //Variable dcb contenant la configuration du port
        HANDLE hCom; //Handle du port COM
        BOOL fSuccess; // Tout est bien passé 
        COMMTIMEOUTS tTimeout;
        int TimeoutRead; 
     
    	char *message_VINST, 
            //Déclaration des msg de TX
    	char  *msgVINST;	
    	//Déclaration des Buffer de RX
    	char   *inBuffer_VINST;
     
    	//Dcélaration des structures
    	struct TrameSending V_INST;
    	struct Conf_Comm Conf;
     
    	//Allocation mémoire  des msg de TX
     
    	message_VINST =(char*) malloc(TX_TAILLE);
     
    	//Allocation mémoire  des Buffer de RX
        inBuffer_VINST= (char*)malloc(RX_TAILLE);
     
     
     
     
        //Déclaration des trames à envoyer:
     
    	//V_INST
    	V_INST.c1=0x30; V_INST.crc=0xE7; V_INST.c2=0xFF; V_INST.c3=0xFF; V_INST.c4=0xFF;
     
    	//Déclaration des paramètres de la trame
            Conf.Parite="Aucune";
    	Conf.StopBit="1";
     
     
       // demande du numéro du port COM
       printf("Entrez le numero du port COM : ");
       scanf("%d", &nPort);
       sprintf(cPort, "\\\\.\\COM%d", nPort);
     
     
        //Ouverture du port Comm
        hCom= CreateFile ( cPort,
                          GENERIC_READ|GENERIC_WRITE, //accés lecture/ecriture
                          0, //pas de partage possible du port une fois ouvert
                          NULL, //pas d'héritage
                          OPEN_EXISTING, //doit etre open_existing
                          0, // pas d'overlopped I/O
                          NULL //hTemplate doit etre null
                     );
        // Vérifier si handle ouvre correctement
        if (hCom ==INVALID_HANDLE_VALUE)
        {
            //Manipuler l'erreur
            printf("Create file failed with error %d\n", GetLastError());
        }
        //Lecture de configuration actuelle
        fSuccess = GetCommState (hCom, &dcb);
        if (!fSuccess)
        {
             //Manipuler l'erreur
            printf("GetCommState failed with error %d\n", GetLastError());
        }
        //Configuration du port:
     
        // gestion de vitesse . (atoi:Convertir String to integer)
        dcb.BaudRate= V9600;
     
        //gestion de la taille
        dcb.ByteSize= BITS_8;
     
     
        // Gestion de la partité
        if (strcmp (Conf.Parite, "Aucune")==0) //strcmp : si égaux renvoie 0
            dcb.Parity=NOPARITY; // pas de parité
        if (strcmp (Conf.Parite, "Paire")==0)
            dcb.Parity=EVENPARITY;
        if (strcmp (Conf.Parite, "Impaire")==0)
            dcb.Parity=ODDPARITY;
     
     
        //Gestion bit de Stop
        if (strcmp (Conf.StopBit, "1")==0)
            dcb.StopBits= ONESTOPBIT; // 1 bit stop
        if (strcmp (Conf.StopBit, "1.5")==0)
            dcb.StopBits= ONE5STOPBITS; // 1.5 bit stop
        if (strcmp (Conf.StopBit, "2")==0)
            dcb.StopBits= TWOSTOPBITS; // 2 bit stop
     
        //Configurer le port
        fSuccess = SetCommState(hCom, &dcb);
        if (!fSuccess)
        {
            //Manipuler l'erreur
            printf("SetCommState failed with error %d\n", GetLastError());
        }
        else
        {
            printf("périphérique initialisé correctement \n \n");
        }
     
        fSuccess = GetCommTimeouts(hCom,  &tTimeout); 
        if (!fSuccess)
        {
             //Manipuler l'erreur
            printf("GetCommTimeouts failed with error %d \n", GetLastError());
        }
     
        //Définition des timeouts
     
        TimeoutRead= MAX_WAIT_READ;
        tTimeout.ReadIntervalTimeout= TimeoutRead;
        tTimeout.ReadTotalTimeoutMultiplier=0;
        tTimeout.ReadTotalTimeoutConstant=TimeoutRead;
        tTimeout.WriteTotalTimeoutMultiplier=0;
        tTimeout.WriteTotalTimeoutConstant=0;
     
        //Configuration du Timeout
        fSuccess = SetCommTimeouts(hCom, &tTimeout);
        if (!fSuccess)
        {
            //Manipuler l'erreur
            printf("SetCommTimeouts failed with error %d\n", GetLastError());
        }
     
     
        //V_INST:
        sprintf(message_VINST, "%c", V_INST.c1);
        sprintf(message_VINST+1, "%c", V_INST.c2);
        sprintf(message_VINST+2, "%c",  V_INST.c3);
        sprintf(message_VINST+3, "%c", V_INST.c4);
        sprintf(message_VINST+4, "%c",  V_INST.crc);
        Ecriture (message_VINST,hCom );
        msg =Lecture(inBuffer,hCom, fSuccess ); //recevoir n'importe quoi
        //fermer le port
        CloseHandle(hCom);
     
        // Traiter V_INST:
        uint32_t VI=Str_To_uint32 (msgVINST);
        uint32_t VI1 =Jeu_Octets(VI);
        float V__INST=VINST (VI1);
        printf("V_INST= %f \n", V__INST);
     
            //Libérer la mémoire
     
        free(message_VINST);
     
        return (fSuccess);
        }
    Voilà la réponse sur Code::Blocks:
    Nom : Capture_codeblocks.PNG
Affichages : 688
Taille : 47,6 Ko

    Alors que avec VS:
    Nom : Capture.PNG
Affichages : 779
Taille : 44,6 Ko

    Je n'arrive pas à trouver le problème. Donc si quelqu'un pourra m'aider SVP.


    Merci

  2. #2
    Nouveau membre du Club Avatar de johntheripper
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2016
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mars 2016
    Messages : 43
    Points : 33
    Points
    33
    Par défaut
    1) Pour Codeblocks que j'utilise souvent, il faut telecharger la version avec le compilateur mingw. part sur le site de codeblocks et telecharge la version avec mingw, tu n'auras plus de probleme
    2) tu peux utiliser l'editeur de code ATOM qui est mon preferée tu l'installe sur ta machine, apres avoir installlé tu doit installer le compilateur gcc sous ta machine et tout y est.
    le plus abordable est que avec linux tout est moins compliqué.
    Au délà des codes de language, il y a la reflexion!

  3. #3
    Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2015
    Messages
    75
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 31
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mars 2015
    Messages : 75
    Points : 59
    Points
    59
    Par défaut
    Merci pour votre réponse.

    Oui avec Code::Blocks, j'utilise le compilateur mingw et déjà tout marche bien. Mon problème apparait quand j'ai changé Visual Studio.
    Sinon pour moi je préfère travailler avec Code::Bocks. Je l'utilise depuis un moment et tout marche bien. Mais, vu que je suis en stage et à l'entreprise ou je travaille utilise VS et surtout aussi que je dois faire une IHM qui lance la lecture des registres de la carte.


    Merci

  4. #4
    Nouveau membre du Club Avatar de johntheripper
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2016
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mars 2016
    Messages : 43
    Points : 33
    Points
    33
    Par défaut
    je ne peux te mentir mais VS je ne l'ai jamais utiliser moi j'utilise le plus ATOM et souvent Codeblocks mais essai d'envoyer l'erreur sur google et j'en suis sure que tu trouveras une reponse google est notre reference à tous
    Au délà des codes de language, il y a la reflexion!

  5. #5
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    A mon avis, ton code ne marchait pas très bien avec CodeBlocks mais simplement CodeBlocks ne faisait pas certaines vérifications que fait Visual Studio. Et là, il a détecté un problème qui était déjà dans ton code. Le message d'erreur me laisse penser que tu écris en dehors d'une zone que tu as alloué dans le tas (heap en anglais) mais Google devrait t'en dire plus sur la signification complète de l'erreur. Il s'avère que dans ton code, il y a effectivement des malloc() et free() donc ça ne semble pas déconnant.

    En regardant ton code, je constate que tu fais un malloc() sur inBuffer_VINST mais que tu ne t'en sers pas. Y compris, tu ne libères pas la mémoire avec free().

    Concernant message_VINST, qui est l'autre pointeur utilisant une zone fournie par malloc(), tu remplis la zone avec 5 caractères, ça à l'air OK mais ensuite tu la passes à la fonction Ecriture() qu'on ne connait pas et je me demande comment elle connait la taille...

    Personnellement, je te conseille d'utiliser un débogueur mémoire comme expliqué ici https://www.developpez.net/forums/d1...ows-and-linux/

  6. #6
    Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2015
    Messages
    75
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 31
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mars 2015
    Messages : 75
    Points : 59
    Points
    59
    Par défaut
    Merci pour votre réponse.

    En regardant ton code, je constate que tu fais un malloc() sur inBuffer_VINST mais que tu ne t'en sers pas. Y compris, tu ne libères pas la mémoire avec free().
    c'est juste une faute de frappe, car en fait j'ai modifié le long code pour le mettre ici. Mais en réalité inBuffer_VINST est passé dans la fonction Lecture :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    msg =Lecture(inBuffer_VINST ,hCom, fSuccess );
    Voilà ma fonction Ecriture:

    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>
    #include <winbase.h>
    #include <conio.h>
    #include <string.h>
    #ifndef Ecriture_H
    #define Ecriture_H
     
    #define TX_TAILLE 5
     
     
     
    BOOL Ecriture (char *message, HANDLE hCom )
    {
     
     
        BOOL fSuccess;
        unsigned long nBytesWrite;
     
     
     
        //Ecrire dans le fichier
        fSuccess=WriteFile(hCom, message,TX_TAILLE, &nBytesWrite, NULL);
        if (!fSuccess)
        {
            //Manipuler l'erreur
            printf("WriteFile failed with error %d\n", GetLastError());
        }
        else
        {
            printf("Ecriture correcte \n");
        }
        free(message);
        return fSuccess;
    }
    #endif // Ecriture_H
    Merci

  7. #7
    Membre expérimenté

    Homme Profil pro
    Responsable des études
    Inscrit en
    Mars 2009
    Messages
    553
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Responsable des études
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2009
    Messages : 553
    Points : 1 672
    Points
    1 672
    Par défaut
    Comment ça se fait que cette ligne au début de ton code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("Entrez le numero du port COM : ");
    n'apparaisse pas dans tes captures d'écran ???

  8. #8
    Membre expérimenté

    Homme Profil pro
    Responsable des études
    Inscrit en
    Mars 2009
    Messages
    553
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Responsable des études
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2009
    Messages : 553
    Points : 1 672
    Points
    1 672
    Par défaut
    Citation Envoyé par abyass Voir le message
    J'ai copié mon code qui marchait très bien avec Code::Blocks, quand je build, la lecture plante. Et je n'arrive pas à comprendre pourquoi.
    Citation Envoyé par abyass Voir le message
    Voilà ma fonction Ecriture:
    Du coup, c'est pas plutôt la fonction Lecture qu'il faudrait nous montrer ?

  9. #9
    Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2015
    Messages
    75
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 31
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mars 2015
    Messages : 75
    Points : 59
    Points
    59
    Par défaut
    Citation Envoyé par nnovic Voir le message
    Comment ça se fait que cette ligne au début de ton code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("Entrez le numero du port COM : ");
    n'apparaisse pas dans tes captures d'écran ???
    Merci pour votre réponse.

    En fait, au début j'ai demandé de donner le num de port mais après j'ai commenter cette partie et je l'ai initialisé dans mon code par le num correspondant. C'est juste que je ne l'ai pas changé ici.

  10. #10
    Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2015
    Messages
    75
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 31
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mars 2015
    Messages : 75
    Points : 59
    Points
    59
    Par défaut
    Citation Envoyé par nnovic Voir le message
    Du coup, c'est pas plutôt la fonction Lecture qu'il faudrait nous montrer ?
    Merci pour votre réponse
    Voilà ma fonction Lecture:

    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>
    #include <winbase.h>
    #include <conio.h>
    #include <string.h>
    #include "DumpHex.h"
    #ifndef Lecture_H
    #define Lecture_H
     
    #define RX_TAILLE 5
     
    char* Lecture (char *inBuffer, HANDLE hCom, BOOL fSuccess )
    {
     
    	char *msg=NULL;
        unsigned long nBytesRead;
        nBytesRead=0; 
     
        //Lecture sur le port
        fSuccess=ReadFile(hCom, inBuffer, RX_TAILLE, &nBytesRead, NULL);
        if (!fSuccess)
        {
            //Manipuler l'erreur
            printf("ReadFile failed with error %d\n", GetLastError());
        }
        else if (nBytesRead==0) // pas des octets lus
            printf("pas de chaine reçue \n");
     
        else if(memchr(inBuffer, '\0', RX_TAILLE)!=NULL && strlen(inBuffer) == nBytesRead-1) //Reçu une chaîne de caractères valide et complète
         {
             printf("chaine recue est: %s\n", inBuffer); //Afficher la chaîne reçue.
         }
        else 
        {
            printf("Donnees recues : \n");
    		msg=DumpHexa(inBuffer, nBytesRead);
     
    		return msg;
     
        } 
     
        return msg;
    }
    #endif
    Et voilà la fonction DumpHexa.

    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
    # include<stdio.h>
    #include<stdint.h>
    #ifndef DumpHex_H
    #define DumpHex_H
    #define BASE 16
    #define _CRT_SECURE_NO_WARNINGS
     
    #include <Windows.h>
     
    char* DumpHexa(char const * pcvDebut, size_t taille)
    {
    	char *msg;
    	char const *pcBytes = pcvDebut;
    	unsigned char theByte;
    	size_t i;
     
        msg = (char*) malloc(5);
     
     
    	theByte = pcBytes[0];
        sprintf(msg, "%02X", theByte);
        for(i=1 ; i<(taille-1) ; i++)
    	{
    		unsigned char theByte_i = pcBytes[i];
    		sprintf((msg+2*i), "%02X", theByte_i);
     
    	}
    	printf(" %s\n\n", msg);
    	return msg ;
     
    }
    #endif // DumpHex_H
    En fait, pour cette partie je l'ai réalisé avec l'aide de quelques membres de ce forum .

  11. #11
    Membre expérimenté

    Homme Profil pro
    Responsable des études
    Inscrit en
    Mars 2009
    Messages
    553
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Responsable des études
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2009
    Messages : 553
    Points : 1 672
    Points
    1 672
    Par défaut
    Bon alors je réponds vite fait avant de partir au bureau, donc à vérifier, mais il me semble que tu remplis un tableau de 5 caractères avec 5 caractères lus depuis le port COM, et que tu essayes ensuite de manipuler ce tableau de 5 caractères comme une chaine de caractères...
    MAIS: tu as oublié qu'une chaine de caractères doit se terminer par '\0'.
    Donc, pour une chaine de caractères qui contiendrait au plus 5 caractères, il faut que le tableau qui la stocke ait une taille de 6. Toutes les fonctions qui dépendent de ce '\0' terminal vont échouer plus ou moins violemment: le printf, le strlen, etc...
    SAUF SI: par hasard, le compilateur que tu utilises place ce tableau juste à côté d'une zone de la mémoire qui est initialisée à zéro. Donc, si ça marchait avant, c'était juste un gros coup de bol.

  12. #12
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    D'ailleurs, ce 5 montre un problème de partage d'information : un coup on a 5 écrit en dur dans le code, un coup on a deux fois le même define dans deux fichiers distincts. Si un jour tu veux mettre 10, tu vas sans doute oublier un endroit et te planter.

    Si des constantes sont utilisées dans plusieurs fichiers *.c, alors il faut utiliser un fichier *.h pour "définir" ces constantes et inclure ce fichier *.h dans tous les fichiers *.c qui en ont besoin.

  13. #13
    Membre expérimenté
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 543
    Points : 1 745
    Points
    1 745
    Par défaut
    Bonjour,

    Citation Envoyé par nnovic Voir le message
    Bon alors je réponds vite fait avant de partir au bureau, donc à vérifier, mais il me semble que tu remplis un tableau de 5 caractères avec 5 caractères lus depuis le port COM, et que tu essayes ensuite de manipuler ce tableau de 5 caractères comme une chaine de caractères...
    MAIS: tu as oublié qu'une chaine de caractères doit se terminer par '\0'.
    Donc, pour une chaine de caractères qui contiendrait au plus 5 caractères, il faut que le tableau qui la stocke ait une taille de 6. Toutes les fonctions qui dépendent de ce '\0' terminal vont échouer plus ou moins violemment: le printf, le strlen, etc...
    SAUF SI: par hasard, le compilateur que tu utilises place ce tableau juste à côté d'une zone de la mémoire qui est initialisée à zéro. Donc, si ça marchait avant, c'était juste un gros coup de bol.
    Ça me rappelle une discussion déjà débattu #23 et que je cite quelques éléments que j’ai avancés dont certains points n’ont absolument pas changé cas de la fonction lecture et écriture :

    Citation Envoyé par sambia39 Voir le message
    Mise à part ce que les autres membres du forum, on dit, j’ajouterais juste quelque remarque.
    Premièrement pour être sur et éviter des erreurs éventuelles, il ne serait pas déconnant de mettre un \0 à la fin de chaîne lue comme ça en est sûr que l’on a bien une chaîne de caractère et que l’on pourra faire les manipulations adéquates et adapter par la suite et honnêtement ; je ne vois à aucun moment où l’on rajoute la séquence de fin de chaîne. Ceci dit, c’est peut-être voulu même après que la fonction ReadFile est renvoyée vrai.
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    fSuccess = ReadFile(hCom, inBuffer, 5, &nBytesRead, NULL);
    if ( fSuccess && ( 0 < nBytesRead) ){
    	fprintf(stderr, "Debug\t:%d",  GetLastError() );
    	inBuffer[nBytesRead] = '\0';
    }else{
    	/*
    	 *  Faire le necessaire
    	 */
    	CloseHandle(hCom);
    	return EXIT_FAILURE;
    }

    Il est essentiel important de comprendre que les fonctions GetCommTimeouts & SetCommTimeouts peuvent être la cause (dans le cas actuel ou futur) de certaines erreurs. Il faut savoir que ces deux fonctions donnent des résultats qui sont imprévisibles soit à cause du temps imparti (temps a écoulé voir beaucoup trop tôt ou alors le temps adéquat n’a pas été déterminer) ou alors si je peux dire tout simplement de la façon dont on a initialisé et configuré la chose. Plus clairement le comportement de ReadFile et WriteFile est régi par les délais d'attente qui peuvent fournir des résultats imprévisibles si vous ne parvenez pas à définir des valeurs de temporisation satisfaisante.

    Plus en détail, si l’on définit ReadIntervalTimeout et/ou ReadTotalTimeoutMultiplier à MAXDWORD et que l’a attribué à ReadTotalTimeoutConstant une valeur supérieure à zéro et inférieure à MAXDWORD, le comportement de ReadFile est directement impacter. Lorsque la fonction ReadFile sera appelée et que s’il y a des data dans votre buffer, ReadFile retourne immédiatement vrai avec les data qui sont dans le buffer (Dans votre cas ici buffer est inBuffer).
    Dans un autre cas, s’il n'y a pas de data dans le buffer ReadFile va boucler jusqu'à ce qu'une data arrive et retourne vrai immédiatement. Et si aucune data arrive dans le délai imparti déterminer par ReadTotalTimeoutConstant il y a time out tous simplement.
    Donc, par précautions dans un premier temps (debug) je conseille de connaître l’état de ReadFile en utilisant GetLastError même si elle retourne vraie.
    En plus, j'avais posé les questions suivantes à savoir si vous êtes en mode synchrone ou asynchrone, car le choix de la fonction de lecture sera différent (ReadFile/ReadFileEx) même-ci ReadFile font les deux tous comme WriteFille (WriteFileEx).

    Prenons le cas de ReadFile. La vérification de fin de lecture est totalement différente du mode synchrone et asynchrone. En mode synchrone, ReadFile retourne vraie, mais en même temps cela signifie que ReadFile a également assigné la valeur NULL à la variable pointée par le lpNumberOfBytesRead qui est un pointeur sur une variable qui reçoit le nombre d'octets lus par la mémoire tampon et ReadFile définit cette variable à zéro avant de procéder à toute vérification de lecture ou d'erreur et donc, si vous êtes en mode asynchrone, il faut attribuer cette variable la valeur NULL pour éviter d’avoir des corruptions, mais attention, on le met à NULL uniquement si lpOverlapped n’est pas NULL.
    Donc si l’on est dans le cas d’une lecture en mode synchrone ça reviendrait exactement à faire comme dans mon précédent message :
    Code C : 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
     
    fSuccess=ReadFile(hCom, inBuffer, 5, &nBytesRead, NULL);
    if ( fSuccess && ( 0 < nBytesRead) ){
        fprintf(stderr, "Debug\t:%d",  GetLastError() );
        inBuffer[nBytesRead] = '\0';
    }else{
        /*
         *  Faire le necessaire
         */
        CloseHandle(hCom);
        return EXIT_FAILURE;
    }
     
    // ou 
     
    fSuccess = ReadFile(hCom, &inBuffer, 5, &nBytesRead, NULL);
    if ( fSuccess &&  (nBytesRead == 0) ){
    	//Faire quelque chose
    }
    	//Faire quelque choses.

    Dans le cas du mode asynchrone cela demande que l’on surveille le retour des fonctions GetOverlappedResult et GetLastError l’un retourne le résultat des opération effectuer et l’autre retourne les types d'erreurs donc (exemple ERROR_HANDLE_EOF). En clair, on teste ici la valeur des retours de ces fonctions dans le but de savoir si l’on a bien tout lu.
    Attention le code sources ci-dessous n'a pas été testé donc il est susceptible de comporter des erreurs :
    Code C : 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
    71
     
    bool f_readAsynchr( HANDLE pFile, HANDLE pEvent ){
     
     
    	DWORD rt_errno = 0;
    	DWORD byRead = 0;
    	bool rt_readloop = true;
     
    	bool rt_read = false;
    	char buffer[BUFSIZ];
    	OVERLAPPED overs = {0};
     
    	DWORD nbRead = BUFSIZ;
    	DWORD szFile = GetFileSize(pFile, NULL);
     
    	while(rt_readloop ){
     
    		rt_readloop = false;
    		rt_read = ReadFile(pFile, buffer, 
    			BUFSIZ, byRead , overs);
    		rt_errno = GetLastError();
     
    		if( false ==  rt_read ){
     
    			if( ERROR_HANDLE_EOF == rt_errno ){
    				fprintf(stderr, "(%d)\t: %s\n",
    					"Erreur mode asynchrone\n")
    				return false;  // 
     
    			}else if( ERROR_IO_PENDING == rt_errno ){
    				bool bread = true;
    				fprintf( stderr, "Lecture des data en ...\n");
     
    				while(bread){
    					bread = false;
    					rt_read = GetOverlappedResult(pFile, &overs, 
    						byRead, false);
     
    					if( false == rt_read ){
    						switch( (rt_errno = GetLastError() )){
    							case ERROR_HANDLE_EOF: 
    								(void)fprintf(stderr, "EOF détecte\n");
    								break;
    							case ERROR_IO_INCOMPLETE:
    								(void)fprintf( stderr, "\t->Opération de lecture en cours.....")
    								bread = true;
    								rt_readloop = true;
    								break;
    							default:
    								(void)fprintf(stderr, "Echec de lecture fin de fichier\n");
    								/*
    								*	Break ou faire le nécéssaire
    								*/
    								break;
    						}
    					}
    					/*
    					*	faire le nessaire si tout a été lue
    					*/
    				}
    			}
     
    		}
    		/*
    		*	Faire le necessaire par la suite s
    		*	sortie de boucle par exemple cas anormale retoune false
    		*/
    		rt_readloop = true;
    	}
    		return true;
    }



    Encore une chose à titre informatif
    Citation Envoyé par abyass Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    /*************************************
    pour utiliser printf et sprintf correctement
    *************************************** */
    #define _CRT_SECURE_NO_WARNINGS
    La ligne de cette macro #define _CRT_SECURE_NO_WARNINGS ne permet absolument pas d’utiliser printf et sprint correctement "à la lecture de votre commentaire" cela permet juste d’inhiber les avertissements de dépréciation de certaines fonctions a sujet à caution dont printf et sprintf font partie. En clair, cela fait taire le compilateur en lui disant d’ignorer les avertissements de dépréciation ainsi donc, les problèmes de sécurité liés à ces fonctions ne vont absolument pas disparaître juste parce que l’on veut utiliser printf ou sprintf correctement en inhibant les avertissements du compilateur bien au contraire elle sont toujours présente. Si vous souhaitez utiliser printf ou sprintf correctement, il existe des fonction alternative que Microsoft préconise printf_s et sprintf_s. printf_sl'un vérifie la chaîne de format pour les caractères et l'autre vérifie si la chaîne de format comporte des caractères de mise en forme qui sont valides. Bref ce n'est pas une très bonne idée de désactiver les avertissements du compilateur juste parce que l'on veut faire taire le compilateur.

    à bientôt
    Celui qui peut, agit. Celui qui ne peut pas, enseigne.
    Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien,
    et les philosophes, qui ne connaissent rien sur tout.
    George Bernard Shaw

  14. #14
    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
    Dans DumpHexa(), pourquoi alloues-tu une taille fixe de 5 alors que tu remplis avec une taille dépendant de taille?
    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.

Discussions similaires

  1. [SDL 1.2] problème de compilation avec Code:Block
    Par RiNoXuS dans le forum SDL
    Réponses: 3
    Dernier message: 08/05/2015, 16h02
  2. [OCILIB] Problème de compilation avec code::blocks
    Par dbqg7322 dans le forum Interfaces de programmation
    Réponses: 2
    Dernier message: 11/01/2013, 13h21
  3. Problème de compilation avec Code Block
    Par med19972004 dans le forum Code::Blocks
    Réponses: 2
    Dernier message: 16/09/2011, 16h32
  4. Problème de compilation avec Code::Blocks
    Par xvid110 dans le forum OpenCV
    Réponses: 12
    Dernier message: 13/06/2011, 23h12
  5. Problème de compilation avec Code Block
    Par med19972004 dans le forum C++
    Réponses: 5
    Dernier message: 04/02/2011, 23h49

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