2009-07-22 6 views

Répondre

2

Les structures explicites C# ont des problèmes en ce qui concerne les références/membres de taille pointeur. Parce que vous devez spécifier explicitement l'emplacement, mais "sizeof (IntPtr)" n'est pas une constante de compilation (contrairement à C++ sizeof), il est impossible d'utiliser des membres de taille pointeur dans des structures explicites lorsque votre assembly doit être utilisable dans les deux processus 32 bits et 64 bits.

En outre, il est possible d'utiliser struct explicites de « convertir » entre les références et pointeurs:

[StructLayout(LayoutKind.Explicit)] 
struct Test 
{ 
    [FieldOffset(0)] 
    public IntPtr ptr; 
    [FieldOffset(0)] 
    public string str; 
} 

Lorsque vous faites cela, votre Assemblée doivent obtenir l'autorisation de code non sécurisé; et il y a le problème que le GC ne saura pas quoi faire avec le contenu struct - est-ce un pointeur que le GC devrait suivre, ou est-ce juste un nombre entier?

Donc, pour répondre à votre question: "Y a-t-il quelque chose que vous pouvez faire avec les unions C++ que vous ne pouvez pas faire avec C# Structures explicites?"

Oui, il est parfois utile en C++ de presser deux bits de données dans les bits inférieurs d'un pointeur. Cela est possible car les deux bits de pointeur les plus bas seront toujours 0 lorsque le pointeur est aligné. Heck, si vous écrivez une liste doublement liée d'entiers de deux bits, vous pourriez même stocker les deux pointeurs et les données dans 32 bits! ("prev^next^data", voir XOR linked list)

Cependant, vous ne pouvez rien faire de semblable en C#, car vous confondriez le GC.

+0

Marshaling a à voir avec la mise en page une fois qu'il devient des données natives. L'IntPtr est toujours un type C#. Jusqu'à ce qu'il soit rassemblé dans une zone de données, il existe en tant que membre sous la plate-forme gérée. –

1

Non, pas vraiment. L'attribut LayoutKind est un moyen de transmettre des données Marshall dans des unions C++ dans interop. C'est en fait beaucoup plus flexible que le mot-clé union en C++, puisque vous avez un contrôle complet sur la disposition en C# avec les structures.

+0

-1 Ceci est complètement faux. Explicit est conçu pour vous donner plus de flexibilité pour contrôler les décalages exacts. Le support syndical n'était pas une préoccupation majeure, et beaucoup de choses (comme les tableaux qui se chevauchent et d'autres types de non-tableaux) ne fonctionnent pas du tout. –

0

Vous ne pouvez pas superposer un tableau d'un autre type sur des données. Par exemple, vous ne pouvez pas superposer les octets [4] et int16, int16. Il va planter au moment de l'exécution.

Questions connexes