2009-07-22 10 views

答えて

2

C#明示的な構造体には、参照/ポインタサイズのメンバーに関していくつかの問題があります。

明示的に位置を指定する必要があるが、 "sizeof(IntPtr)"はコンパイル時定数ではないため(C++のsizeofとは異なります)、アセンブラを使用可能にするには明示的な構造体でポインタサイズのメンバーを使用することはできません32ビットと64ビットの両方のプロセスで使用できます。

はまた、参照とポインタの間で「変換」するために、明示的な構造体を使用することが可能である:あなたがこれを行うと

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

、あなたのアセンブリは、安全でないコードの許可が必要になります。 GCが構造体の内容をどうするのかわからないという問題があります.GCが追跡するポインタか、それは単なる整数ですか?

あなたの質問に答えてください: "C#でできないものはありますか?+明示的な構造体ではできません"

はい、ポインタの下位ビットに2ビットのデータを圧縮することはC++で役に立ちます。ポインターが整列されているとき、ポインターの2つの最下位ビットは常に0になるため、これが可能です。

2ビット整数の二重リンクリストを作成している場合は、ポインタとデータの両方を32ビットで保存することもできます。 ( "prev^next^data"、XOR linked listを参照してください)

しかし、GCを混乱させるので、C#のようなことはできません。

+0

マーシャリングは、ネイティブデータになったらレイアウトと関係します。 IntPtrはまだC#型です。データ領域にマーシャリングされるまでは、管理対象プラットフォームの下にメンバとして存在します。 –

1

いいえ、実際はありません。 LayoutKind属性は、interop内のC++共用体にデータをマーシャリングする方法です。 C#の構造体を使ってレイアウトを完全に制御できるので、C++のunionキーワードよりはるかに柔軟です。

+0

-1これは完全に間違っています。 Explicitは、正確なオフセットをより柔軟に制御できるように設計されています。連合サポートは主要な関心事ではなく、重複配列やその他の非配列型のような多くのものはまったく機能しません。 –

0

データの上に別のタイプの配列を重ねることはできません。たとえば、byte [4]とint16、int16をオーバーレイすることはできません。実行時にクラッシュします。

関連する問題