Serialisation binaire dans un flux mémoire [Résolu]

renyone 71 Messages postés vendredi 9 mars 2007Date d'inscription 12 avril 2010 Dernière intervention - 4 juil. 2008 à 11:45 - Dernière réponse : renyone 71 Messages postés vendredi 9 mars 2007Date d'inscription 12 avril 2010 Dernière intervention
- 10 juil. 2008 à 17:08
Salut, j'ai l'impression que quelquechose m'échappe et je sollicite donc votre aide.

J'ai une méthode de sérialisation binaire dans un flux mémoire de la forme:

public

unsafe
static
string FormatTypes<T>(T myObject){

BinaryFormatter bf =
new
BinaryFormatter();

MemoryStream ms =
new
MemoryStream();bf.Serialize(ms, myObject);

ms.Close();

byte[] buffer = ms.ToArray();

...

}

Quand j'essaye tout bêtement de sérialiser un sbyte, la tailler de buffer est de 51 alors que je m'attendais à avoir plutot 1 vu que les sbytes sont stockés sur 1 octet.

Quelqu'un aurait-il une idée la dessus?

Merci d'avance.
Afficher la suite 

Votre réponse

7 réponses

Meilleure réponse
cs_niky 168 Messages postés jeudi 28 juin 2001Date d'inscription 18 octobre 2008 Dernière intervention - 4 juil. 2008 à 19:29
3
Merci
Un byte[] .Net est l'équivalent de char* en C. Tout comme char[] et Int16[] sont l'équivalent de short* (car les char .Net sont stocké sur 2 octets).

Je présume que tu dois posséder une DLL et que tu souhaites appeler une fonction de cette DLL.
Par exemple, pour appeler une fonction C qui a le prototype suivant et qui est exposé dans la DLL nommée "mylib.dll" :
int myfunction(char *input)

C'est une fois en C# où tu peux commencer à faire un peu n'importe quoi. En fait, pour représenter un pointeur, tu peux avoir plusieurs notations qui sont équivalentes
[DllImport("mylib.dll")]
static extern int myfunction(byte[] input);
ou
[DllImport("mylib.dll")]
static extern int myfunction(ref byte input);
ou
[DllImport("mylib.dll")]
static extern int myfunction(IntPtr input);
et même, car un pointeur n'est rien d'auteur qu'un entier :
[DllImport("mylib.dll")]
static extern int myfunction(int input);

Après, le compilateur .Net ne te permettra pas d'appeler ces 3 écritures avec un byte[] en premier argument (seule la première sera acceptée par le compilo). Toutefois, toutes ces écritures reviennent à passer un char*.
Tu trouveras de la litterature là dessous en recherchant autour des termes Interop et Marshal.

Merci cs_niky 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 73 internautes ce mois-ci

Commenter la réponse de cs_niky
SharpMao 1025 Messages postés mardi 4 février 2003Date d'inscription 7 juin 2010 Dernière intervention - 4 juil. 2008 à 12:30
0
Merci
Hello,

C'est parce que la sérialisation binaire garde certaines informations en plus, comme le type de l'objet sérialisé.

Si tu enregistre le contenu de ton buffer dans un fichier et que tu l'ouvres avec un notepad, tu verras, en plus de certains caractères de contrôles : "System.SByte" et "m_value" écris en toutes lettres.

Amicalement, SharpMao

"C'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!"
(Coluche / 1944-1986 / Pensées et anecdotes)
Commenter la réponse de SharpMao
cs_niky 168 Messages postés jeudi 28 juin 2001Date d'inscription 18 octobre 2008 Dernière intervention - 4 juil. 2008 à 12:31
0
Merci
Salut,

C'est parfaitement normal.
La sérialisation ne consiste pas seulement à stocker les types simples (int, string, byte, bool, etc).
Si tu sérialises des classes, le framework doit stocker le nom de la classe. Si plus est les classes que tu sérialises ont des liens entre elles, ces références doivent être enregistrés aussi.
Commenter la réponse de cs_niky
renyone 71 Messages postés vendredi 9 mars 2007Date d'inscription 12 avril 2010 Dernière intervention - 4 juil. 2008 à 13:07
0
Merci
Merci de vos réponses.

Mais dans ce cas, comment recupérer (désérialiser) les données "essentielles" comme la valeur du sbyte placé en paramètre? Parce que je dois récupérer ce tableau de bytes (buffer dans le code ci-dessus) et l'utiliser dans une fonction C++ qui aura pour but de le décoder.

Pour résumer:

fonction c# qui sérialise mes données dans un flux mémoire ==> tableau de bytes [] ==> fonction c++ qui décode (désérialise) le tableau de sbyte (char*).

Merci !

A+
Commenter la réponse de renyone
cs_niky 168 Messages postés jeudi 28 juin 2001Date d'inscription 18 octobre 2008 Dernière intervention - 4 juil. 2008 à 14:54
0
Merci
Typiquement, la sérialisation bnaire est spécifique à chaque environnement : Java sérialise d'une certaine manière, .Net de sa manière, etc.
La bibliothèque standard de C++ ne possède pas de moteur de sérialisation.

Pour échanger un tableau de entre .Net et C++ (je ne parle pas de C++ .Net), tu as la possibilité
- de passer un pointeur sur ton tableau (c'est ce qui est fait quand on appel une API Windows en .Net)
- d'écrire dans un fichier (assez moyen comme technique)
- de passer par un méthode standardisé d'échange de données (c'est typiquement le cas de SOAP/CORBA, RPC)
Commenter la réponse de cs_niky
renyone 71 Messages postés vendredi 9 mars 2007Date d'inscription 12 avril 2010 Dernière intervention - 4 juil. 2008 à 15:00
0
Merci
Merci Nicky.

Je pensais effectivement passer un pointeur sur le tableau. La méthode c# doit obligatoirement renvoyer un tableau de bytes (ce n'est pas moi qui décide...) que je dois passer sous forme de pointeurs de caractères (char*) à ma méthode c++.

A ce niveau j'ai un problème: comment convertir ce bytes[] en char* ?
Commenter la réponse de renyone
renyone 71 Messages postés vendredi 9 mars 2007Date d'inscription 12 avril 2010 Dernière intervention - 10 juil. 2008 à 17:08
0
Merci
Effectivement, tout ceci peut se trouver dans la litterature, en tappant interoperabilité c# c++ par exemple. Il est res facile d'utiliser la classe Marshall ensuite.
Merci bien!
Commenter la réponse de renyone

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.