c# c++ unions

Unión C++ en C#



unions (6)

Estoy traduciendo una biblioteca escrita en C ++ a C #, y la palabra clave ''union'' existe una vez. En una estructura

¿Cuál es la forma correcta de traducirlo a C #? Y que hace? Se ve algo como esto;

struct Foo { float bar; union { int killroy; float fubar; } as; }


En C / C ++, la unión se utiliza para superponer diferentes miembros en la misma ubicación de memoria, por lo que si tiene una unión de un int y un float ambos usan los mismos 4 bytes de memoria para almacenar, obviamente escribir uno daña al otro (ya que int y float tienen diferentes diseños de bits).

En .Net, Microsoft optó por la opción más segura y no incluyó esta característica.

EDITAR: a excepción de la interoperabilidad


Personalmente, ignoraría la UNIÓN todos juntos e implementaría Killroy y Fubar como campos separados

public struct Foo { float bar; int Kilroy; float Fubar; }

El uso de UNION ahorra 32 bits de memoria asignados por el int .... no va a hacer o deshacer una aplicación en estos días.


Puede usar diseños de campo explícitos para eso:

[StructLayout(LayoutKind.Explicit)] public struct SampleUnion { [FieldOffset(0)] public float bar; [FieldOffset(4)] public int killroy; [FieldOffset(4)] public float fubar; }

No probado. La idea es que dos variables tengan la misma posición en su estructura. Por supuesto, solo puedes usar uno de ellos.

Más información sobre sindicatos en struct tutorial


Realmente no se puede decidir cómo lidiar con esto sin saber algo sobre cómo se usa. Si simplemente se usa para ahorrar espacio, entonces puedes ignorarlo y simplemente usar una estructura.

Sin embargo, esa no es la razón por la cual se usan los sindicatos. Hay dos razones comunes para usarlos. Una es proporcionar 2 o más formas de acceder a los mismos datos. Por ejemplo, una unión de un int y una matriz de 4 bytes es una (de muchas) maneras de separar los bytes de un entero de 32 bits.

El otro es cuando los datos en la estructura provienen de una fuente externa, como un paquete de datos de red. Por lo general, un elemento de la estructura que contiene la unión es una identificación que le indica qué sabor de la unión está vigente.

En ninguno de estos casos puede ignorar ciegamente la unión y convertirla a una estructura donde los dos (o más) campos no coinciden.


Si está utilizando la union para mapear los bytes de uno de los tipos, entonces en C # puede usar BitConverter .

float fubar = 125f; int killroy = BitConverter.ToInt32(BitConverter.GetBytes(fubar), 0);

o;

int killroy = 125; float fubar = BitConverter.ToSingle(BitConverter.GetBytes(killroy), 0);


public class Foo { public float bar; public int killroy; public float fubar { get{ return (float)killroy;} set{ killroy = (int)value;} } }