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

Contribuez .NET Discussion :

[C#]Conversion struct <-> byte[] [Sources]


Sujet :

Contribuez .NET

  1. #1
    Expert confirmé
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Par défaut [C#]Conversion struct <-> byte[]


    Je sais pas, ça pourrai être utile.
    Avec cette classe on peut :
    - récupérer un byte[] à partir d'un struct
    - récupérer un struct à partir d'un byte[]
    - idem en remplaçant byte[] par un stream
    * A priori les struct doivent avoir l'attribut StructLayout(LayoutKind.Sequential)

    using :
    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    using System;
    using System.IO;
    using System.Collections.Generic;
    using System.Runtime.InteropServices;

    code :
    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
    72
    73
    74
    75
    76
    77
     
    public static class StructGetter
        {
            public static void WriteBlock(Stream Output, object structure)
            {
                byte[] buf = new byte[SizeOf(structure)];
                WriteBlock(Output, structure, buf);
            }
     
            public static void WriteBlock(Stream Output, object structure, byte[] buf)
            {
                GetBytes(structure, buf, 0, buf.Length);
                Output.Write(buf, 0, SizeOf(structure));
            }
     
            public static object ReadBlock(Stream Input, Type structure_type)
            {
                byte[] buf = new byte[Marshal.SizeOf(structure_type)];
                return ReadBlock(Input, structure_type, buf);
            }
     
            public static object ReadBlock(Stream Input, Type structure_type, byte[] buf)
            {
                if (Input.Read(buf, 0, Marshal.SizeOf(structure_type)) < Marshal.SizeOf(structure_type))
                    throw new DreamShield.Data.InvalidDataException("Stream too short");
     
                return GetStruct(buf, 0, Marshal.SizeOf(structure_type), structure_type);
            }
     
            public static int SizeOf(object structure)
            {
                return Marshal.SizeOf(structure);
            }
     
            public static void GetBytes(object val,
                                          [In, Out] byte[] buffer,
                                         int offset,
                                        int bufsize)
            {
                if (val == null)
                    throw new ArgumentNullException("val");
     
                int size = SizeOf(val);
                IntPtr p = Marshal.AllocHGlobal(size);
     
                try
                {
                    Marshal.StructureToPtr(val, p, true);
                    Marshal.Copy(p, buffer, offset, bufsize);
                }
                finally
                {
                    Marshal.FreeHGlobal(p);
                }
            }
     
            public static object GetStruct(byte[] buffer,
                                           int offset,
                                           int count,
                                           Type struct_type)
            {
                IntPtr p = Marshal.AllocHGlobal(count);
                object result = null;
     
                try
                {
                    Marshal.Copy(buffer, offset, p, count);
                    result = Marshal.PtrToStructure(p, struct_type);
                }
                finally
                {
                    Marshal.FreeHGlobal(p);
                }
     
                return result;
            }
        }

  2. #2
    Rédacteur/Modérateur
    Avatar de Skalp
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2006
    Messages
    1 694
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 694
    Par défaut
    Peux-tu me (nous?) donner un exemple concret d'utilisation de cette classe statique ?
    A mon niveau, je ne vois pas dans quel cadre cela peut être utilisé.
    Merci !

  3. #3
    Expert confirmé
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Par défaut
    Le cas le plus basique est l'échange de struct avec de l'interop ou dans un stream.
    Par exemple, pour écrire dans un fichier avec un certain format, plutôt que de créer un StreamWriter et écrire séparément chaque champ du struct, imaginons :
    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    [StructLayout(LayoutKind.Sequential)]
    struct
    {
      public int a;
      public int b;
      public int c;
      public int d;
      public int e;
      public double t;
      public long u;
      ...
    }
    ( Ce qui est long ) on peut faire directement StructGetter.WriteBlock(...). (C'est dans ce cadre que je l'utilise personnellement : soit pour lire un fichier dont le format est écrit en C++ sous forme de struct ou pour mon propre format de fichiers).
    ça équivaut un peut au c++ lorsqu'on gère directement une struct comme un pointeur et qu'on l'envoi un peut partout.

Discussions similaires

  1. Conversion de tableau de byte en types primitifs
    Par soft0613 dans le forum API standards et tierces
    Réponses: 3
    Dernier message: 14/03/2008, 15h14
  2. Conversion de char[] en byte[]
    Par Razgriz dans le forum Langage
    Réponses: 12
    Dernier message: 12/09/2007, 11h36
  3. Conversion Strinf file en Byte[]
    Par Tail dans le forum Entrée/Sortie
    Réponses: 3
    Dernier message: 04/09/2006, 16h34
  4. [Conversion] Comment transformer un byte[] en String ?
    Par Elbarto dans le forum Langage
    Réponses: 8
    Dernier message: 02/01/2006, 01h37
  5. [Conversion]convertir int[] en bytes[]
    Par tony_big_guy dans le forum Langage
    Réponses: 5
    Dernier message: 02/05/2005, 15h47

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