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 :

byte[] vers string


Sujet :

C#

  1. #1
    Rédacteur
    Avatar de Neitsa
    Homme Profil pro
    Chercheur sécurité informatique
    Inscrit en
    Octobre 2003
    Messages
    1 041
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur sécurité informatique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 041
    Par défaut byte[] vers string
    Bonjour à tous,

    langage: C#
    Framework .NET: 2.0 et sup.
    O.S: Windows XP et sup.

    Je dispose d'une bibliothèque dynamique (DLL) programmée en C. L'appel d'une des fonctions exportées par cette DLL me retourne une structure.

    Grâce à Pinvoke, je "marshal" ma structure pour qu'elle soit compréhensible en C#. Jusque là pas de problème.

    Un bout de la structure C:

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    #pragma pack(1)
    typedef struct  tag_TRPACKET{
       long Flag;
       long Transition;
       char Provider[16];
       //[...]
    } TRPACKET;
    #pragma pack()

    La même en C#:

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
        [StructLayout(LayoutKind.Sequential, Pack=1, CharSet=CharSet.Ansi)] //size: 60
        public struct TRPACKET{        
            public int Flag;        
            public int Transition;        
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16, ArraySubType= UnmanagedType.LPStr)]
            public byte[] Provider; // size: 16
            //[...]
    }

    N.B: Notez que le membre "Provider" est de type byte[], mais le mettre en char[] ne change rien au problème...

    Problématique

    La fonction C me rempli le tableau de caractère "Provider" avec une chaîne ANSI (i.e. un octet par caractère). Notez que chacun des caractères retournés dans le buffer "Provider" est obligatoirement dans l'espace imprimable ( 0x20 >= caractère <= 0x7E). Le caractère final de la chaine est toujours un '\0'

    Le problème est que les appels subséquent à la fonction ne nettoie pas le buffer complètement. Ça ne pose pas de problème en C, mais en C#, cela m'en pose un. Exemples:

    - 1er appel à la fonction. La fonction C me retourne "ABCDE\0" dans le buffer "Provider":
    Provider vaut {0x41, 0x42, 0x43, 0x44, 0x45, 0x00} soit "ABCDE\0".
    - 2eme appel, la fonction me retourne "FGH\0":
    Provider vaut {0x46, 0x47, 0x48, 0x00, 0x45, 0x00, /*... */}
    Comme on le voit ci-dessus, la fonction ne nettoie pas le buffer, puisque le 0x45 ('E') de l'appel précédent est encore présent.

    Lorsque j'imprime la chaine de caractère (via console.WriteLine()) la chaîne imprimée pour le deuxième cas vaut : "FGH E", ce qui n'est pas ce que j'attends.

    Notez que le conversion byte[] => string est réalisée avec: ASCIIEncoding.ASCII.GetString() ou Encoding.UTF8.GetString()

    J'ai essayé pas mal de chose outre les deux méthodes ci-dessus pour qu'un '\0' exprime bien une fin de chaîne pour C# mais je n'ai rien trouvé de satisfaisant.

    Du coup j'ai pondu une fonction mais ça me semble être une rustine plutôt que quelque chose d'acceptable en l'état:

    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
     
            //search for the first '\0' and truncate the buffer at this offset
            static string StringFromByteArray(byte[] array)
            {
                int i;
                bool found = false;
                for (i = 0; i < array.Length; i++)
                    if (array[i] == '\0')
                    {
                        found = true;
                        break;
                    }
                string str = null;
                if(found)
                    str = Encoding.UTF8.GetString(array, 0, i);            
     
                return str;
            }

    Existe-t-il un moyen propre de faire une conversion de ce genre, c'est à dire que C# prenne le premier '\0' dans le buffer comme le caractère terminateur de chaine ?

    Merci à vous.

  2. #2
    Membre émérite
    Avatar de maxim_um
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    895
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 895
    Par défaut
    Salut Neitsa;

    Je n'y connais rien en C#,
    mais à tout hasard, as-tu essayé avec GetChars() ?

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Il suffit de déclarer le champ comme string dans le structure C#, le marshalling s'occupe du reste. Il faut juste lui préciser le type de chaine, et la taille de la chaine :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
        [StructLayout(LayoutKind.Sequential, Pack=1, CharSet=CharSet.Ansi)] //size: 60
        public struct TRPACKET{        
            public int Flag;        
            public int Transition;        
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
            public string Provider; // size: 16
            //[...]
    }
    Donc pas la peine de t'embêter à faire manuellement la conversion avec Encoding

  4. #4
    Rédacteur
    Avatar de Neitsa
    Homme Profil pro
    Chercheur sécurité informatique
    Inscrit en
    Octobre 2003
    Messages
    1 041
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur sécurité informatique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 041
    Par défaut
    Hello,

    Merci à tous deux pour vos réponses. La solution de tomlev était la bonne !

    J'avais déjà essayé avec le type string, mais j'avais du essayer avec un autre "UnmanagedType" et du coup ça plantait au runtime, donc je n'avais pas poursuivi dans cette voie là.

    Phewwwww ! Vraiment ça m'aide beaucoup, mon code est beaucoup plus clair comme cela.

    Un grand merci !

  5. #5
    Membre émérite
    Avatar de maxim_um
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    895
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 895
    Par défaut
    Bon ben c'est cool.

    Sinon il y a la méthode String.IndexOf () qui aurait pu avantageusement remplacer ta fonction StringFromByteArray.

    Bon, sur ce coup-là, ça ne sert plus à rien, mais comme je repasse sur ce topique autant le dire.

    Bonne continuation les gars.

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

Discussions similaires

  1. Covertir byte[] vers string rapidement
    Par foufar2009 dans le forum Langage
    Réponses: 6
    Dernier message: 23/04/2010, 17h59
  2. conversion de byte vers string
    Par dalilnet dans le forum Langage
    Réponses: 5
    Dernier message: 18/07/2008, 15h05
  3. [Conversion] Comment transformer un byte[] en String ?
    Par Elbarto dans le forum Langage
    Réponses: 8
    Dernier message: 02/01/2006, 01h37
  4. [debutant]Convertir un pointeur byte en String
    Par patmaba dans le forum SL & STL
    Réponses: 3
    Dernier message: 22/07/2005, 13h34
  5. [C#] Convertir des bytes en string
    Par sorcer1 dans le forum Windows Forms
    Réponses: 8
    Dernier message: 03/02/2005, 15h52

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