Marshalling tableau de structs vs classes

Je souhaite lire une structure native dans un type C # à l’aide de Marshalling. Ma méthode pour structurer les structures est la suivante:

T ReadObject(BinaryReader br) { var bytes = br.ReadBytes(Marshal.SizeOf(typeof(T))); var handle = GCHandle.Alloc(bytes, GCHandleType.Pinned); try { return (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T)); } finally { handle.Free(); } } 

Maintenant, cela fonctionne bien en général, le problème se pose avec le type suivant:

 [StructLayout(LayoutKind.Sequential, Pack=1)] class SubData { public short A1; public short A2; } [StructLayout(LayoutKind.Sequential, Pack=1)] class Data { public short Id; [MarshalAs(UnmanagedType.ByValArray, SizeConst=3)] public SubData[] SubDatas; } 

Notez que cela fonctionne bien si SubData est une structure ! Mais si SubData est une classe, Marshal.PtrToStructure lance une erreur FatalExecutionEngineError. J’aimerais restr avec des classes car parfois mes types ont des valeurs par défaut et les structures ne peuvent pas avoir d’initialiseurs de champs ni de constructeurs par défaut, et certains de ces types sont plutôt volumineux.

Merci pour l’aide.

Edit: le message d’erreur est “Le moteur d’exécution a rencontré une erreur irrécupérable. L’adresse de l’erreur était à 0x6af99aec, sur le thread 0x348. Le code d’erreur est 0xc0000005. Cette erreur peut être un bogue du CLR ou du code non sécurisé ou non. des parties vérifiables du code utilisateur. Les sources courantes de ce bogue incluent les erreurs de marshaling utilisateur pour COM-interop ou PInvoke, susceptibles de corrompre la stack. ”

Une classe est un type de référence. Ainsi, lors de l’utilisation de Marshal.PtrToStructure, elle copiera un pointeur et aucune valeur à la position de Subdata.
Lors de la déclaration de Subdata en tant que structure, les valeurs réelles de Subdata seront copiées.
Ainsi, lors du Marshalling, vous devez utiliser une structure. Vous pouvez aussi toujours avoir une classe, qui utilisera la version de struct dans un constructeur.
Vous pouvez par exemple le prouver en utilisant

taille de

pour voir que les tailles seront différentes.