1

それが問題です。C#の明示的な構造体ではできない、c ++ユニオンでできることはありますか?

4

3 に答える 3

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# Explicit 構造体ではできないことで、C++ 共用体でできることはありますか?」

はい、C++ では、2 ビットのデータをポインターの下位ビットに絞り込むことが役立つ場合があります。これが可能になるのは、ポインターがアラインされている場合、ポインターの最下位 2 ビットが常に 0 になるためです。

2 ビット整数の二重連結リストを作成している場合、ポインタとデータの両方を 32 ビットで格納することもできます。(「前の ^ 次の ^ データ」、XOR リンク リストを参照)

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

于 2009-07-22T01:25:09.200 に答える
1

いいえ、そうではありません。LayoutKind属性は、相互運用でデータをC++ユニオンにマーシャルする方法です。構造体を使用してC#のレイアウトを完全に制御できるため、実際にはC++のunionキーワードよりもはるかに柔軟性があります。

于 2009-07-22T00:16:59.403 に答える
0

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

于 2012-01-26T20:25:09.730 に答える