Salut,
J'ai un problème étrange avec Marshal.SizeOf...
Je souhaite manipuler la structure native suivante (en-tête d'un fichier bitmap) :
Code C : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 typedef struct tagBITMAPFILEHEADER { WORD bfType; DWORD bfSize; WORD bfReserved1; WORD bfReserved2; DWORD bfOffBits; } BITMAPFILEHEADER, *PBITMAPFILEHEADER;
J'ai donc écrit l'équivalent en C# :
Le layout explicite est nécessaire pour que le marshalling n'aligne pas les champs sur les bornes de 32bits (ça décalerait tous les champs à partir du 2e, ce qui corromprait l'en-tête).
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 [StructLayout(LayoutKind.Explicit)] private struct BITMAPFILEHEADER { public static readonly short BM = 0x4d42; // BM [FieldOffset(0)] public short bfType; [FieldOffset(2)] public int bfSize; [FieldOffset(6)] public short bfReserved1; [FieldOffset(8)] public short bfReserved2; [FieldOffset(10)] public int bfOffBits; }
Quand je copie cette structure vers la mémoire non-managée avec Marshal.Copy, le layout explicite est bien pris en compte et les données binaires sont correctes.
Par contre, Marshal.SizeOf me renvoie 16
Pourtant, j'ai beau compter et recompter, ça fait 14... d'ailleurs si j'écris 16 octets d'en-tête, le fichier est incorrect et illisible. Si je ne tiens pas compte de ce que dit Marshal.Sizeof et que j'utilise une taille de 14, ça fonctionne nickel.
En fait, on dirait qu'il ne tient pas compte du layout explicite dans le calcul de la tailleJ'ai aussi essayé avec l'opérateur sizeof (dans un bloc unsafe), le résultat est le même.
Bref, je ne trouve aucun moyen d'obtenir une taille correcte autrement qu'en la codant en dur. Quelqu'un aurait une idée de comment faire ? Ou une explication de ce comportement ?
Partager