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

Langage Delphi Discussion :

Mix LitteEndian-BigEndian dans un fichier binaire


Sujet :

Langage Delphi

  1. #1
    Membre expérimenté
    Avatar de Gouyon
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    1 081
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 1 081
    Points : 1 521
    Points
    1 521
    Billets dans le blog
    5
    Par défaut Mix LitteEndian-BigEndian dans un fichier binaire
    Bonjour à tous

    J'utilise le code ci dessous pour sauvegarder des données numériques dans un fichier binaire.

    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
     
      ficcrt := TFileStream.Create(nomfic, fmCreate);
      valeur := traces.Count;
      ficcrt.Write(valeur, sizeof(integer));
      for num in traces.Keys do
      begin
        if traces.TryGetValue(num, seg) then
        begin
          ficcrt.Write(num, sizeof(uint64));
          valeurd := seg.minlon;
          ficcrt.Write(valeurd, sizeof(double));
          valeurd := seg.maxlon;
          ficcrt.Write(valeurd, sizeof(double));
          valeurd := seg.minlat;
          ficcrt.Write(valeurd, sizeof(double));
          valeurd := seg.maxlat;
          ficcrt.Write(valeurd, sizeof(double));
          valeur := seg.getNbPoints;
          ficcrt.Write(valeur, sizeof(integer));
          for i := 0 to valeur - 1 do
          begin
            if seg.getLonLat(i, lon, lat) then
            begin
              ficcrt.Write(lon, sizeof(double));
              ficcrt.Write(lat, sizeof(double));
            end;
          end;
        end;    
      end;
      ficcrt.Free;
    Pas de problème pour le relire ensuite en pascal
    Par contre j'ai eu besoin de le relire avec un programme en C (Compilateur visual studio) et là grosse surprise je lis bien tous les entiers par contre les réel c'est n'importe quoi.
    Et pour cause quand j'ai analysé le fichier binaire je me suis aperçu que les entiers sont sauvegardé en littleEndian et les réels en bigEndian
    Y a t'il quelque part une option de compilation qui impose ça???
    Il y a des jours où j'éprouve une haine profonde envers microsoft et Apple c'est pas mieux
    Mon modeste site et mes modestes oeuvres sont
    Rémi

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 534
    Points : 25 082
    Points
    25 082
    Par défaut
    C'est avant tout lié à l'architecture du processeur et de l'OS
    Si cela se trouve cela a pu changer entre du x86 32bits et le 64bits, par exemple le type Extended 32Bits est réduit à un Double en 32Bits (et c'est un 64bits sur Linux)
    Echanger du binaire c'est toujours périlleux, il faut définir précisément chaque champ, un par un, avec des machines, je n'ai échangé que des entiers et des caractères avec un charset spécifique, je me suis pas intéressé au double, j'avais même pas penser que lui aussi était sous l'influence du Endianness.

    Tenter un SWAP processeur

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function ByteSwap(const a : Int64) : int64;
    asm
    {$IFDEF CPUX64}
      BSWAP RCX;
      MOV RAX, RCX;
    {$ELSE}
      MOV EDX,[EBP+$08];
      MOV EAX,[EBP+$0C];
      BSWAP EAX;
      BSWAP EDX;
    {$ENDIF CPUX64}
    end;
    tente une variante function ByteSwap(const a : Double) : Double; en espérant que le type Double passe en registre directement sinon ça demande quelques efforts de plus.


    Converting Double Types from Little Endian to Big Endian Using Variant Record

    Sans passer par un SWAP asm, essaye ceci :

    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
    type
      //enumeration used in variant record
      BytePos = (EndVal, ByteVal);
     
      PEndianCnvRec = ^EndianCnvRec;
     
      EndianCnvRec = packed record
        case pos: BytePos of
           //The value we are trying to convert
          EndVal: (EndianVal: double);           
           //Overlapping bytes of the double
          ByteVal: (Bytes: array[0..SizeOf(Double)-1] of byte); 
      end;
     
    //A gets B's values swapped
    procedure SwapBytes( A, B: PEndianCnvRec );
    var
      i: integer;
    begin
      for i := high(A.Bytes) downto low(A.Bytes) do
        A.Bytes[i] := B.Bytes[High(A.Bytes) - i];
    end;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
      a,b,c: EndianCnvRec;
    begin
      a.EndianVal := 23344.55555;
      SwapBytes(@b,@a);
      ShowMessage(FloatToStr(b.EndianVal));
      SwapBytes(@c,@b);
      ShowMessage(FloatToStr(c.EndianVal));
    end;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 448
    Points
    28 448
    Par défaut
    je suis surpris de ta problématique...pour un même processeur Delphi ou C ça doit donner le même boutisme.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  4. #4
    Membre expérimenté
    Avatar de Gouyon
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    1 081
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 1 081
    Points : 1 521
    Points
    1 521
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    je suis surpris de ta problématique...pour un même processeur Delphi ou C ça doit donner le même boutisme.
    Oui moi aussi j'ai été très surpris. Mais les faits sont là. Pour préciser je suis effectivement en 64bits des 2 cotés.
    Maintenant que je le sais je vais faire l'inversion coté C ou passer mes double en entier ce qui serait faisable étant donné la précision dont j'ai besoin
    Il y a des jours où j'éprouve une haine profonde envers microsoft et Apple c'est pas mieux
    Mon modeste site et mes modestes oeuvres sont
    Rémi

Discussions similaires

  1. Lecture ecriture dans un fichier binaire
    Par laetous dans le forum C
    Réponses: 13
    Dernier message: 26/08/2006, 08h50
  2. Réponses: 12
    Dernier message: 26/07/2006, 12h08
  3. Réponses: 2
    Dernier message: 27/06/2006, 14h33
  4. [LG]ecriture dans un fichier binaire
    Par jsaviola dans le forum Langage
    Réponses: 3
    Dernier message: 26/12/2003, 17h30

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