그게 질문입니다. C# Explicit structs로 할 수없는 C++ 유니온으로 할 수있는 일이 있습니까?(.net) .net Explicit structs와 C++ Union의 본질적인 차이점이 있습니까?
답변
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++ 노조로 할 수있는 일이 있나요?
예, 포인터의 하위 비트에 2 비트의 데이터를 집어 넣는 것이 C++에서 유용 할 때가 있습니다. 이는 포인터가 정렬 될 때 포인터의 두 최하위 비트가 항상 0이기 때문에 가능합니다.
지저귐, 2 비트 정수의 이중 연결 목록을 작성하는 경우 포인터와 데이터를 모두 32 비트로 저장할 수도 있습니다. ("prev^next^data", XOR linked list 참조)
그러나 GC를 혼동하는 것처럼 C#에서는 이와 같은 작업을 수행 할 수 없습니다.
아니요. LayoutKind 속성은 interop에서 데이터를 C++ 유니온으로 마샬링하는 방법입니다. 구조체를 사용하여 C#의 레이아웃을 완벽하게 제어 할 수 있으므로 C++의 union 키워드보다 훨씬 유연합니다.
-1 이것은 완전히 잘못되었습니다. 명시 적 (Explicit)은 정확한 오프셋을 제어 할 수있는 유연성을 제공합니다. 유니언 지원은 주요 관심사가 아니었고 중복 배열 및 기타 비 배열 유형과 같은 많은 것들이 전혀 작동하지 않습니다. –
데이터 위에 다른 유형의 배열을 겹칠 수 없습니다. 예를 들어, byte [4]와 int16, int16을 오버레이 할 수 없습니다. 런타임에 충돌이 발생합니다.
마샬링은 일단 네이티브 데이터가되면 레이아웃과 관련이 있습니다. IntPtr은 여전히 C# 형식입니다. 데이터 영역에 마샬링되기 전까지는 관리되는 플랫폼 아래에 구성원으로 존재합니다. –