9
votes

Taille des structures dans .NET

Mon problème est d'envoyer une structure entre un programme en C à un programme C #.

J'ai fait une structure en C #: p> xxx pré>

la taille totale du La structure doit être de 20 octets. P>

Lorsque je fais un taille de () code> en C ++ de cette structure, P>

System.Diagnostics.Debug.WriteLine(
    "SizeOf(NetPoint) = " +
    System.Runtime.InteropServices.Marshal.SizeOf(new NetPoint()));


4 Réponses :


2
votes

Essayez d'ajouter l'attribut [Structlayout (Layoutkind.Euite, Pack = 1)] et voyez ce qui se passe. Je soupçonne un rembourrage de 8 octets, alors il est 3x8 octets.


1 commentaires

Non, objet dans .NET (sauf pour les primitives comme INT) ont une taille plus que la somme des champs.



7
votes

En fait, techniquement, la structure doit être un minimum de 20 octets. Si vous allouez plus lors de l'envoi, le récepteur n'utilisera tout simplement pas / les copier. Le problème est toujours sous-complétaire.

Cela dit, je vois le problème. Hmm. Je pense que le problème est le dernier long ... que l'IMHO est aligné à huit octets, injectant quatre octets vides auparavant. Je pense qu'il y a une pénalité de performance pour avoir un élément de huit octets non aligné à une limite de huit octets.

joindre StructLayout attributs pour déterminer le décalage de chaque élément manuellement. Ensuite, vous devriez pouvoir obtenir des choses en ligne.

Référence: Comment Pour contrôler la disposition physique des champs de données dans le fichier .NET Framework 2.0 xxx

qu'au moins doit aligner des éléments à une limite d'une octet . Vous pouvez également aller plus loin en définissant le début exact de chaque élément, si nécessaire.


1 commentaires

Votre solution fonctionne aussi. Merci beaucoup. Votre solution semble être plus facile que la réponse de John. Je vais utiliser votre solution .. au revoir



9
votes

En règle générale, les processeurs de qualité aiment avoir des variables alignées en mémoire à un endroit un emplacement uniforme de leur taille, de sorte qu'un entier de quatre octets devrait être sur une adresse de mémoire divisible par quatre, et un huit Byte long doit être à une adresse divisible par huit.

Les concepteurs de langue C # (et C ++) le savent, et ils inséreront le rembourrage dans des structures pour fournir l'alignement nécessaire. Donc, la disposition réelle de votre structure ressemble à ceci: xxx

Vous pouvez résoudre ce problème en faisant la première valeur, en règle générale, si vous mettez toujours les plus grandes valeurs à Le début de vos structures, vous n'aurez aucun rembourrage inséré pour préserver l'alignement des membres.

Vous pouvez également le réparer en ajoutant xxx

avant La Déclaration de la structure, mais cela entraînera un mal aligné longtemps qui blesse les performances. Sur certains processeurs, cela fait mal de la performance. (Le Alpha Axp Défaut sur les membres mal alignés, par exemple). X86 Les CPU n'ont qu'une pénalité de performance mineure, mais il y a un risque de futurs processeurs ayant une majeure Pénalité de performance, il est donc préférable de concevoir vos structures pour aligner correctement (plutôt que de les emballer) si vous le pouvez.


1 commentaires

Wow, j'aime ce type de commentaires. Je viens d'apprendre quelque chose de nouveau et d'intéressant.



1
votes

TomTom a répondu à cette question plutôt bien je pense, mais il y a une autre alternative si vous vous retrouvez dans une situation de structure complique de com. Chaque champ peut être aligné sur ses propres attributs de champ de champ.

[StructLayout(LayoutKind.Explicit)]
public struct COMPoint
{
    [FieldOffset(0)] public int X;
    [FieldOffset(4)] public int Y;
}


0 commentaires