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 :

Ordre en mémoire des variables dans une structure


Sujet :

C

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Septembre 2011
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Septembre 2011
    Messages : 11
    Points : 8
    Points
    8
    Par défaut Ordre en mémoire des variables dans une structure
    Bonjour,

    je rencontre un problème assez étrange, j'ai une structure UserInfo :

    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
     
    typedef struct _UserInfo
    {	
    char Name[256];
    char Email[256];
    char TelephoneMobile[50];
    char  TelephoneMobile[50];
     
    long BadLoginCount;
    bool IsAccountLocked; 
     
    time_t PasswordExpirationDate;
    time_t LastLogin;
     
     
    }   UserInfo;
    J’utilise cette structure dans une DLL crée sous Visual C++ 2010 Express
    et les fonctions de cette DLL sont utilisées dans un programme compilé sous GCC dans Code::Block. (par chargement explicite de la dll)

    exemple : GetUserInfoAD(UserInfo *ret)

    le problème c'est que dans cette fonction les valeurs sont correctement attribuées a la structure,
    mais dans mon projet quand j'utilise la fonction de ma dll et que j'affiche les valeurs, j'ai les 4 char ( Name,Email, TelephoneMobile, TelephoneMobile) qui sont correctement affiché, mais les autres variables ( BadLoginCount,BadLoginCount,PasswordExpirationDate;LastLogin)
    non.

    En faite j'ai remarqué que selon dans quel ordre je déclare les variables dans ma structure, valeurs changent ou sont inversées entre les variables !
    J'ai bien tenté de trouver la bonne combinaison mais j'ai toujours une variable qui n'a pas la bonne valeur .
    Je précise que je re-compile bien sur, la DLL et l'EXE à chaque fois que je modifie la structure.
    J'ai lu que les compilateurs effectuent des modifications au seins de la structure ( padding ?)

    comment faire pour uniformiser la structure entre les deux compilateurs ? ou faire en sorte de forcer la même optimisation?

    merci beaucoup d'avance,

    cordialement

  2. #2
    Expert éminent
    Avatar de transgohan
    Homme Profil pro
    Développeur Temps réel Embarqué
    Inscrit en
    Janvier 2011
    Messages
    3 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Temps réel Embarqué

    Informations forums :
    Inscription : Janvier 2011
    Messages : 3 146
    Points : 9 386
    Points
    9 386
    Par défaut
    Sous certains compilateurs microsoft tu peux le configurer avec #pragma pack(n).

    « Toujours se souvenir que la majorité des ennuis viennent de l'espace occupé entre la chaise et l'écran de l'ordinateur. »
    « Le watchdog aboie, les tests passent »

  3. #3
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Bonjour,

    Citation Envoyé par transgohan Voir le message
    Sous certains compilateurs microsoft tu peux le configurer avec #pragma pack(n).
    C'est dommage de rendre le code moins portable ( #pragma n'étant pas standard et pas accepté par tous les compilateurs ) pour cela.

    De plus, je sais qu'en C++ il y a des incompatibilité entre les compilateurs au niveau des .dll car certains aspects comme l'héritage ne sont pas gérés de la même manière.
    Je ne demande donc si en C on ne peut pas avoir d'autres problèmes de ce type (?).
    Je pense que la meilleure solution serait de se créer un petit cmakeLists.txt et de compiler le projet pour chaque compilateurs qu'on souhaite utiliser (?).
    Ceci permettrait peut être (?) d'éviter de mauvaises surprises.

  4. #4
    Expert éminent
    Avatar de transgohan
    Homme Profil pro
    Développeur Temps réel Embarqué
    Inscrit en
    Janvier 2011
    Messages
    3 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Temps réel Embarqué

    Informations forums :
    Inscription : Janvier 2011
    Messages : 3 146
    Points : 9 386
    Points
    9 386
    Par défaut
    Il n'existe pas de solution portable de toute manière (hormis des hacks, voir en bas de mon post).

    La norme c++11 défini alignas : http://en.cppreference.com/w/cpp/language/alignas
    Mais ce n'est pas supporté par les compilateurs microsoft.

    Un post intéressant sinon : http://stackoverflow.com/questions/6...ulate-alignast

    Edit :
    Avec GCC pour supprimer le padding :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct test{
      int a;
      char b;
      int c;
    } __attribute__((__packed__));
    C'est strictement équivalent au pack(1).
    https://www.securecoding.cert.org/co...ucture+padding

    Ou bien tu peux explicitement rajouter ton propre padding.

    « Toujours se souvenir que la majorité des ennuis viennent de l'espace occupé entre la chaise et l'écran de l'ordinateur. »
    « Le watchdog aboie, les tests passent »

  5. #5
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    c'est un problème de padding.

    La solution la plus propre, ne pas rendre visible cette structure et faire dans ta DLL des fonctions qui lisent ou écrivent les valeurs de cette structure.
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  6. #6
    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
    Citation Envoyé par guillaume-13015 Voir le message
    J'ai lu que les compilateurs effectuent des modifications au seins de la structure ( padding ?)
    Le padding consiste à éventuellement rajouter des bits de remplissage (padding, en anglais) pour respecter des contraintes d'alignements des champs dans la mémoire. En revanche, cela ne change aucunement lors de champs ! Les champs sont placés en mémoire dans l'ordre dans lequel ils sont définis dans le code.

    En faite j'ai remarqué que selon dans quel ordre je déclare les variables dans ma structure, valeurs changent ou sont inversées entre les variables !
    N'as-tu pas une fonction qui fait un memset() / memcpy() de la structure au lieu de faire une affectation champ par champ ?

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Septembre 2011
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Septembre 2011
    Messages : 11
    Points : 8
    Points
    8
    Par défaut
    Merci de vos réponses,

    bien noté pour le padding, je vais rajouter ça dans mon code partagé entre les deux compilateurs pour éviter les éventuels futur soucis,

    une fois ce problème de padding résolu, j'ai eu toujours des problèmes mais seulement avec les "time_t"
    je les remplacés par des unsigned int et la ... plus de soucis avec le décalage sur les time_t

    donc j'ai testé un sizeof(time_t), un dans la dll et l'autre dans l'exe
    et je suis très étonné du résultat :

    sizeof(time_t) sous VC++ =8
    sizeof(time_t) sous GCC =4

    comment cela peut être possible ?

  8. #8
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Citation Envoyé par guillaume-13015 Voir le message
    Merci de vos réponses,

    bien noté pour le padding, je vais rajouter ça dans mon code partagé entre les deux compilateurs pour éviter les éventuels futur soucis,

    une fois ce problème de padding résolu, j'ai eu toujours des problèmes mais seulement avec les "time_t"
    je les remplacés par des unsigned int et la ... plus de soucis avec le décalage sur les time_t

    donc j'ai testé un sizeof(time_t), un dans la dll et l'autre dans l'exe
    et je suis très étonné du résultat :

    sizeof(time_t) sous VC++ =8
    sizeof(time_t) sous GCC =4

    comment cela peut être possible ?
    Soit tu compiles en 64 bits sur VC++ et en 32 sur GCC, soit tu n'utilises pas la même implémentation ( la norme ne donne généralement que des tailles minimales pour les types ).
    C'est pour cela que je te conseille, plutôt que d'essayer de bidouiller le code de ta bibliothèque pour qu'une fois compilé avec VC++ il puisse être utilisé par un programme compilé avec GCC de compiler ta bibliothèque avec VC++ pour la version VC++ et avec GCC pour ta version GCC.
    Ceci sera beaucoup plus simple, rapide et sûr.

  9. #9
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Citation Envoyé par guillaume-13015 Voir le message
    sizeof(time_t) sous VC++ =8
    Normal :
    Under Visual Studio 2008, it defaults to an __int64 unless you define _USE_32BIT_TIME_T. You're better off just pretending that you don't know what it's defined as, since it can (and will) change from platform to platform.
    Cf ici : http://stackoverflow.com/questions/4...e-t-typedef-to
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

Discussions similaires

  1. Ordre des variables dans une table
    Par stefsas dans le forum SAS Base
    Réponses: 6
    Dernier message: 02/09/2014, 10h22
  2. ordre des champs dans une structure
    Par oussema dans le forum C
    Réponses: 8
    Dernier message: 08/03/2007, 18h42
  3. Des variables dans une iframe.
    Par kult dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 08/02/2006, 16h29
  4. Réponses: 7
    Dernier message: 23/01/2006, 11h53
  5. [AS2] déclarer des variables dans une fonction
    Par ooyeah dans le forum ActionScript 1 & ActionScript 2
    Réponses: 12
    Dernier message: 02/08/2005, 12h50

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