それが問題です。C#の明示的な構造体ではできない、c ++ユニオンでできることはありますか?
3 に答える
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# ではそのようなことはできません。
いいえ、そうではありません。LayoutKind属性は、相互運用でデータをC++ユニオンにマーシャルする方法です。構造体を使用してC#のレイアウトを完全に制御できるため、実際にはC++のunionキーワードよりもはるかに柔軟性があります。
別の型の配列をデータに重ねることはできません。たとえば、byte[4] と int16、int16 を重ねることはできません。実行時にクラッシュします。