Byte* byte[] string ... je craque

SURTOUT Messages postés 4 Date d'inscription mercredi 4 avril 2007 Statut Membre Dernière intervention 28 janvier 2011 - 19 janv. 2011 à 16:27
cs_Robert33 Messages postés 834 Date d'inscription samedi 15 novembre 2008 Statut Membre Dernière intervention 14 janvier 2017 - 28 janv. 2011 à 22:30
Bonjour a tous,

Voila je bricole un peu en C# pour m'y mettre, je trouve ça vraiment intéressant mais des fois je bute sur des trucs tout betes.

La ca fait 4heures que je me bagarre avec les structures en C#, ca avance un petit peu, mais je bloque complètement sur un truc tout bete:

Dans ma structure j'ai un tableau de byte a taille fixe que j'ai reussi a renseigner avec des characters ascii 8bits, maintenant je voudrais juste afficher le contenu de ce tableau dans une textbox.

Donc je voudrais faire un truc dans le style:

this.textBox1.Text = stMaStructure.bMonTableauDebytes.ToString();
J'ai essayé ça:
this.textBox4.Text = stMaStructure.bMonTableauDebytes.UnsafeAsciiBytesToString(3);

this.textBox4.Text = Convert.ToString(stMaStructure.bMonTableauDebytes, 16);
this.textBox4.Text = System.Text.Encoding.ASCII.GetString(&stMaStructure.bMonTableauDebytes[0], 0, 7);

rien ne fonctionne, j'ai trouvé des choses avec des Marshal quelque chose mais je n'ai rien réussi a faire marcher, curieux que ce soit aussi compliqué ?

Aussi au passage si quelqu'un pouvait m'expliquer la différence entre byte* et byte[] ?

Merci d'éviter les supers reflexions, genre (t'es nul faut penser objet, le C# c'est pas du C etc ... etc ...) je le sais, mais après tout avant de marcher, on ne sait pas marcher, cet exercice fait partie de mon entrainement.

Merci pour votre aide.
A voir également:

7 réponses

SURTOUT Messages postés 4 Date d'inscription mercredi 4 avril 2007 Statut Membre Dernière intervention 28 janvier 2011
19 janv. 2011 à 16:45
Désolé pour le code je rajoute un message:

// Je voudrais faire un truc comme ca
this.textBox1.Text = stMaStructure.bMonTableauDebytes.ToString();

// J'ai essayé ça:
this.textBox4.Text = stMaStructure.bMonTableauDebytes.UnsafeAsciiBytesToString(3);

this.textBox4.Text = Convert.ToString(stMaStructure.bMonTableauDebytes, 16);

this.textBox4.Text = System.Text.Encoding.ASCII.GetString(&stMaStructure.bMonTableauDebytes[0], 0, 7); 
// Mais rien ne fonctionne
0
BunoCS Messages postés 15472 Date d'inscription lundi 11 juillet 2005 Statut Modérateur Dernière intervention 25 mars 2024 103
19 janv. 2011 à 17:21
Hello,
stMaStructure.bMonTableauDebytes est de quel type?
Sinon, c'est quoi le but de la manip? Si tu as juste besoin d'un tableau de caractère ascii...ben...tu peux utiliser une string, non?

@+
Buno
----------------------------------------
L'urgent est fait, l'impossible est en cours. Pour les miracles, prévoir un délai...
Rejoignez mon réseau professionnel sur Viadeo
0
cs_Robert33 Messages postés 834 Date d'inscription samedi 15 novembre 2008 Statut Membre Dernière intervention 14 janvier 2017 33
23 janv. 2011 à 15:45
Bonjour SURTOUT

Ce qu'il faut avant tout svoir, c'est qu'en C# les chaines sont codées en unicode, donc le nombre de bytes n'est pas nécéssairement identique au nombre de caracteres.
Lorsque tu manipules un tableau de bytes le compilateur n'a aucun moyen évident de le transformer en chaine, le codage dans le tableau peut très bien être ASCII ou Unicode mais aussi UTF il faut donc l'aider un peu

voici un bout de code pour une conversion

byte[] array = new byte[10] { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x50};
// on considere que le tableu de byte contient de l'ASCII pur
string str = new string( UnicodeEncoding.ASCII.GetChars(array));


Mais comme le souligne très justement buno, si tu veux manipuler des tableaux de caracteres utilise des 'string' ou des 'StringBuilder', ou encore des char[], mais pas des byte[].

Bon code
Bob.
C# is amazing, enjoy it!
0
SURTOUT Messages postés 4 Date d'inscription mercredi 4 avril 2007 Statut Membre Dernière intervention 28 janvier 2011
24 janv. 2011 à 11:06
buno et robert33, merci pour votre aide.

Tout a fait d'accord avec vous, si aujourd'hui je devais manipuler du texte, je prendrai des string. Malheureusement pour moi, je fais une passerelle d'interface avec un vieux programme de la nuit des temps qui stock toutes ses données sous forme binaire dans un fichier lui aussi binaire.
Donc j'ai plusieurs structures qui sont littéralement le map de ces données dans le fichier. J'ai réussi a lire le fichier et transférer les données dans ma structure.
Je vous explique même pas l'anarchie, tout est mélangé et l'alignement mémoire se fait sur frontière de 1/2 mot.

Donc stMaStructure et bMonTableauDebytes se presentent sous la forme :

    unsafe public struct ST_MA_STRUCTURE
    {
        ...
        public short sShort1;
        public short sShort2;
        public fixed byte bMonTableauDebytes1[7];
        public fixed byte bMonTableauDebytes2[14];
        public float fFloat1;
        ...
    }
    public ST_MA_STRUCTURE stMaStructure = new ST_MA_STRUCTURE();


Toujours le meme probleme avec:
this.textBox4.Text = new string(UnicodeEncoding.ASCII.GetChars(&stMaStructure .bMonTableauDebytes1[0]));

Message: Erreur 2 Argument '1' : impossible de convertir de 'byte*' en 'byte[]'

Ce que je ne comprends pas surtout c'est cette erreur:
impossible de convertir de 'byte*' en 'byte[]'

byte est un octet, byte* est un pointeur sur byte, mais byte[] c'est quoi ?

Ca serait tres simple a faire en C++, mais je veux pas faire une dll pour ca, car c'est repousser la difficulté.

Merci pour votre aide.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_Robert33 Messages postés 834 Date d'inscription samedi 15 novembre 2008 Statut Membre Dernière intervention 14 janvier 2017 33
27 janv. 2011 à 13:31
Bonjour

En C# ce n'est pas comme en C.
Les pointeurs sont implicite sur les objets (Class).
Pour les structures elles sont passées sur la pile, il vaut donc mieux utiliser une Class.
un Byte[] c'est un tableau, en C# le compilateur reconnait le type tableau, donc si une methode attend un tableau tu ne peux pas lui passer l'adresse d'un élément, contrairement au C.
Donc dans to cas :
this.textBox4.Text = new string(UnicodeEncoding.ASCII.GetChars(stMaStructure.bMonTableauDebytes1));

devrait faire l'affaire.
D'une maniere générale, en C# n'utilise jamais les pointeurs et n'utilise la référence que pour les type de base.
les structures "Struct" sont également à proscrire, sauf dans le cas de passage de parametre vers du code natif.
utilise plutôt une classe sans contructeur.

Bob.
C# is amazing, enjoy it!
0
SURTOUT Messages postés 4 Date d'inscription mercredi 4 avril 2007 Statut Membre Dernière intervention 28 janvier 2011
28 janv. 2011 à 10:34
Bonjour Bob et merci pour ton aide,

C'est très intéressant ce que tu écris la.
Donc le C# gere le type tableau dynamic ? Ce qui en C ne serait qu'un pointeur ? Effectivement comme en C le type tableau non dimensionné[] n'existe pas, j'ai vraiment du mal a concevoir le truc.

Dans un premier temps:
this.textBox4.Text = new string(UnicodeEncoding.ASCII.GetChars(stMaStructure.bMonTableauDebytes1));


Genere des erreurs:

Erreur 1 La méthode surchargée correspondant le mieux à 'System.Text.Encoding.GetChars(byte[])' possède des arguments non valides

Erreur 2 Argument '1' : impossible de convertir de 'byte*' en 'byte[]'

Dans un deuxieme temps, a propos des structures, tu as raison, j'ai lu plusieurs articles qui disaient qu'en C# il valait mieux définir une classe plutôt que d'utiliser les structures ce qui me donnait quelque chose comme ça:

    [StructLayout(LayoutKind.Explicit, Size =364,CharSet = CharSet.Ansi)]
    unsafe public class ST_MA_STRUCTURE
    {
        ...
        [FieldOffset(10)]        public short sShort1;
        [FieldOffset(12)]        public short sShort2;
        [FieldOffset(14)]        public fixed byte bMonTableauDebytes1[7];
        [FieldOffset(21)]        public fixed byte bMonTableauDebytes2[14];
        [FieldOffset(35)]        public float fFloat1;
        ...
    }


Et impossible de définir mon tableau de byte, j'avais toujours un message:

Erreur 2 La taille du tableau ne peut pas être spécifiée dans une déclaration de variable (essayez d'initialiser avec une expression 'new')

Au final, j'avais réussi a utiliser ma structure, donc je suis resté sur ce principe, néanmoins ça n'a pas l'air propre du tout. Peut-être que le problème est plus en amont.
Je ne comprends pas pourquoi le C# n'accepte pas la taille fixe de mon tableau de byte?

Je ne décourage pas. Une idée un conseil ?
0
cs_Robert33 Messages postés 834 Date d'inscription samedi 15 novembre 2008 Statut Membre Dernière intervention 14 janvier 2017 33
28 janv. 2011 à 22:30
Bonsoir.

hummm, cela mérite quelques eclaircissements.
les messages d'erreur
Le premier
Erreur 1 La méthode surchargée correspondant le mieux à 'System.Text.Encoding.GetChars(byte[])' possède des arguments non valides
Erreur 2 Argument '1' : impossible de convertir de 'byte*' en 'byte[]'
C'est de ma faute, je n'avais pas fais attention que tu avais Fixé les tableaux dans la structure.
Je pense qu'on ne peut tout simplement pas passer d'un type de tableau Fixé à un Byte[], pour la bonne raison que le dotnet ne comprend pas naturelement ces tableaux Fixés, je crois que cela a été introduit avec la version 2.0 dans le Runtime.InteropServices pour permetre le passage vers du code natif.
il faut donc convertir ces tableaux Fixés en quelque chose de manipulable par du code managé.
Sans garanti je te propose:
unsafe
{
    
    fixed (ST_MA_STRUCTURE* p = &stMaStructure) // on défini un pointeur de travail
    {
        byte[] tab=new byte[7]; // un tableau C# classique
        for ( int i = 0; i< 7; i++) // on copy du tableau fixé vers le classique
            tab[i] =p->bMonTableauDebytes1[i];
        //Là on devrait pouvoir utiliser les fonctions du code natif, attention il faut enlever les \0 en fin de chaines
        string Text = new string(UnicodeEncoding.ASCII.GetChars(tab)).Trim('\0');
    }
}



L'autre erreur maintenant
Erreur 2 La taille du tableau ne peut pas être spécifiée dans une déclaration de variable (essayez d'initialiser avec une expression 'new')

En effet, dans une classe on ne peut pas utiliser de tableau fixé, enfin je crois.
ce type de tableau étant prévu pour le passage vers du code natif non managé via des structure.
bien que tu ais correctement tagué ta classe pour qu'elle ressemble à une structure, ce n'est, pour le C#, pas la même chose.

Revenons sur nos bases.
Si tu vas passer toute ta structure vers un code natif non managé, alors conserve la structure en struct, comme je l'ai noté plus haut c'est le but même de ce type de données.(en fait je croyais que seuls tes tableaux étaient passés vers le code natif.)
Pour pouvoir utiliser tes données dans les 2 modes, écris une petite classe qui encapsule tes données sous forme de propriété classique C# mais possede des méthodes pouvant gerer la structure.


Bob.
C# is amazing, enjoy it!
0
Rejoignez-nous