C++ で記述されたライブラリを C# に変換していますが、キーワード 'union' が 1 回存在します。構造体で。
それをC#に翻訳する正しい方法は何ですか? そして、それは何をしますか?次のようになります。
struct Foo {
float bar;
union {
int killroy;
float fubar;
} as;
}
そのために明示的なフィールド レイアウトを使用できます。
[StructLayout(LayoutKind.Explicit)]
public struct SampleUnion
{
[FieldOffset(0)] public float bar;
[FieldOffset(4)] public int killroy;
[FieldOffset(4)] public float fubar;
}
未テスト。アイデアは、2 つの変数が構造体で同じ位置にあるということです。もちろん、そのうちの 1 つしか使用できません。
構造体チュートリアルの共用体に関する詳細情報
これがどのように使用されているかを知らずに、これに対処する方法を実際に決定することはできません。単にスペースを節約するために使用されている場合は、無視して構造体を使用できます。
ただし、ユニオンが使用される理由は通常ではありません。それらを使用する一般的な理由は 2 つあります。1 つは、同じデータにアクセスする方法を 2 つ以上提供することです。たとえば、int と 4 バイトの配列の結合は、32 ビット整数のバイトを分離する (多くの) 方法の 1 つです。
もう 1 つは、構造体のデータがネットワーク データ パケットなどの外部ソースから来た場合です。通常、共用体を囲む構造体の 1 つの要素は、有効な共用体のフレーバーを示す ID です。
これらのいずれの場合でも、union をやみくもに無視して、2 つ (またはそれ以上) のフィールドが一致しない構造体に変換することはできません。
を使用してunion
1 つの型のバイトを別の型にマップしている場合は、BitConverter
代わりに C# を使用できます。
float fubar = 125f;
int killroy = BitConverter.ToInt32(BitConverter.GetBytes(fubar), 0);
また;
int killroy = 125;
float fubar = BitConverter.ToSingle(BitConverter.GetBytes(killroy), 0);
C/C++ では、共用体は同じメモリ位置に異なるメンバーをオーバーレイするために使用されるため、int と float の共用体がある場合、両方とも同じ 4 バイトのメモリを使用して格納し、明らかに一方に書き込むと他方が破損します ( int と float はビット レイアウトが異なります)。
.Net では、Microsoft はより安全な選択を行い、この機能を含めませんでした。
編集:相互運用を除く
個人的には、UNION をまとめて無視し、Killroy と Fubar を別々のフィールドとして実装します。
public struct Foo
{
float bar;
int Kilroy;
float Fubar;
}
UNION を使用すると、int によって割り当てられた 32 ビットのメモリが節約されます。最近では、アプリを作成または中断することはありません。