code

C #의 C ++ 유니온

codestyles 2020. 11. 5. 08:03
반응형

C #의 C ++ 유니온


C ++로 작성된 라이브러리를 C #으로 번역하고 있는데 'union'이라는 키워드가 한 번 존재합니다. 구조체에서.

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;
}

테스트되지 않았습니다. 아이디어는 두 개의 변수가 구조체에서 동일한 위치에 있다는 것입니다. 물론 그중 하나만 사용할 수 있습니다.

구조체 자습서의 공용체에 대한 추가 정보


당신은 그것이 어떻게 사용되는지에 대해 알지 못하고 이것을 어떻게 처리할지 결정할 수 없습니다. 단순히 공간을 절약하는 데 사용되는 경우 무시하고 구조체를 사용할 수 있습니다.

그러나 그것이 일반적으로 조합이 사용되는 이유는 아닙니다. 그것들을 사용하는 두 가지 일반적인 이유가 있습니다. 하나는 동일한 데이터에 액세스하는 두 가지 이상의 방법을 제공하는 것입니다. 예를 들어, int와 4 바이트 배열의 합집합은 32 비트 정수의 바이트를 분리하는 한 가지 방법입니다.

다른 하나는 구조체의 데이터가 네트워크 데이터 패킷과 같은 외부 소스에서 온 경우입니다. 일반적으로 공용체를 둘러싸는 구조체의 한 요소는 유효한 공용체의 특징을 알려주는 ID입니다.

이 두 경우 모두 합집합을 맹목적으로 무시하고 두 개 이상의 필드가 일치하지 않는 구조체로 변환 할 수 없습니다.


C / C ++에서 공용체는 동일한 메모리 위치에서 다른 멤버를 오버레이하는 데 사용되므로 int와 float의 공용체가 있으면 둘 다 동일한 4 바이트의 메모리를 사용하여 저장하므로 분명히 하나에 쓰면 다른 멤버가 손상됩니다. int와 float는 비트 레이아웃이 다릅니다).

.Net에서 Microsoft는 더 안전한 선택을했으며이 기능을 포함하지 않았습니다.

편집 : interop 제외


를 사용하여 union유형 중 하나의 바이트를 다른 유형으로 매핑하는 경우 C #에서 BitConverter대신 사용할 수 있습니다 .

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

또는;

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

개인적으로 저는 UNION을 모두 무시하고 Killroy와 Fubar를 별도의 필드로 구현합니다.

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

UNION을 사용하면 int ....에 의해 할당 된 메모리의 32 비트가 절약됩니다. 요즘에는 앱을 만들거나 중단하지 않습니다.


public class Foo
{
    public float bar;
    public int killroy;

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

참고 URL : https://stackoverflow.com/questions/126781/c-union-in-c-sharp

반응형