Объединение С++ в С#
Я перевод библиотеки, написанной на С++, на С#, и ключевое слово 'union' существует один раз. В структуре.
Каков правильный способ перевода его на С#? И что он делает? Это выглядит примерно так:
struct Foo {
float bar;
union {
int killroy;
float fubar;
} as;
}
Ответы
Ответ 1
Для этого можно использовать явные поля:
[StructLayout(LayoutKind.Explicit)]
public struct SampleUnion
{
[FieldOffset(0)] public float bar;
[FieldOffset(4)] public int killroy;
[FieldOffset(4)] public float fubar;
}
непроверенная. Идея состоит в том, что две переменные имеют одинаковую позицию в вашей структуре. Конечно, вы можете использовать только один из них.
Дополнительная информация о союзах в struct tutorial
Ответ 2
Вы не можете решить, как с этим справиться, не зная о том, как он используется. Если это просто используется для экономии места, вы можете игнорировать его и просто использовать struct.
Однако обычно это не означает, что используются союзы. Существуют две общие причины их использования. Один из них заключается в предоставлении двух или более способов доступа к тем же данным. Например, объединение int и массив из 4 байтов - это один (из многих) способов выделения байтов из 32-битного целого числа.
Другой - когда данные в структуре поступают из внешнего источника, такого как сетевой пакет данных. Обычно один элемент структуры, охватывающий объединение, - это идентификатор, который сообщает вам, какой аромат объединения действует.
В любом из этих случаев вы не можете слепо проигнорировать объединение и преобразовать его в структуру, где два (или более) поля не совпадают.
Ответ 3
В C/С++ union используется для наложения разных членов в одно и то же место памяти, поэтому, если у вас есть объединение int и flat, они оба используют те же 4 байта памяти, очевидно, что запись на один развращает другую ( поскольку int и float имеют разную компоновку бит).
В .net MS пошел с более безопасным выбором и не включил эту функцию.
EDIT: кроме interop
Ответ 4
Лично я буду игнорировать UNION вместе и реализовать Killroy и Fubar как отдельные поля
public struct Foo
{
float bar;
int Kilroy;
float Fubar;
}
Использование UNION сохраняет 32 бита памяти, выделенных int.... не собирается делать или прерывать приложение в эти дни.
Ответ 5
Если вы используете union
для сопоставления байтов одного из типов с другим, а затем на С#, вы можете использовать BitConverter
вместо этого.
float fubar = 125f;
int killroy = BitConverter.ToInt32(BitConverter.GetBytes(fubar), 0);
или
int killroy = 125;
float fubar = BitConverter.ToSingle(BitConverter.GetBytes(killroy), 0);