저는 stackoverflow에 처음이므로 C# 구조체와 해당 레이아웃에 대한 질문이 있습니다. 구조체에 대한 포인터의 FieldOffset을 고정 바이트 배열과 동일한 값으로 설정
는 이제 다음과 같은 구조체를 가정 해 봅시다 :[StructLayout(LayoutKind.Sequential, Pack = 1)]
public unsafe struct Link
{
// some primitive data (2 integers for example)
}
[StructLayout(LayoutKind.Explicit, Pack = 1)]
public unsafe struct Node
{
[FieldOffset(0)]
public int LinkCount;
[FieldOffset(4)]
public Link* Links;
[FieldOffset(4)]
private fixed byte _linksData[10 * sizeof(Link)];
}
그 이유는 내가 IO-성능에 대한 blittable 유형을 필요로한다는 것입니다. 크기가 몇 GB 인 매우 큰 (노드 당 최대 10 개의 링크) 그래프를 처리해야합니다. 그래프는 노드 구조체의 배열로 표현됩니다. 위와 같은 설정으로 그래프 파일에서 바이트 포인터 (물론 바이트 버퍼를 가리킴)로 100MB를 읽을 수 있고 Node 유형의 포인터로 캐스트 할 수 있기를 바랬습니다. 아주 좋은 성능을냅니다. 처음에는 Node-struct에 Link (Link0, ..., Link10) 유형의 10 개의 개별 변수가 있었지만 정상적으로 작동했습니다. 그러나 위의 Node-struct로 이어지는 컴파일 타임에이 설정을 구성하는 것이 좋을 것입니다.
나는 그것이 동일한 FieldOffset을 가지고 있기 때문에 _linksData와 동일한 메모리 위치를 가리킬 것이라고 기대했다. 그러나 실제로 Links 포인터는 항상 null 포인터입니다.
내 질문은 : 링크가 _linksData와 같은 메모리 위치를 가리키는 방법이 있거나 다른 구조체에 포함 된 구조체의 고정 된 크기의 배열을 갖는 다른 방법이 있습니까? 사전에 모든 답변을
감사합니다 -
마르쿠스
벤 보이트의 게시물을 읽은 후 나는 클래스에 구조체를 변경하지 않고도 비슷한 tryed. 다음은 나를 위해 작동하는 방법입니다.[StructLayout(LayoutKind.Explicit, Pack = 1)]
public unsafe struct Node
{
[FieldOffset(0)]
public int LinkCount;
[FieldOffset(4)]
private fixed byte _linksData[10 * sizeof(Link)];
public Link* GetLinks()
{
fixed(byte* pLinksData = _linksData)
{
return (Link*)pLinksData;
}
}
}
마지막 조각이 곤경에 당신을 얻을 위하여려고하고있다. 포인터는 고정 블록 내부에서만 유효합니다. ONC 당신이 빠져 나왔을 때, 반환 된 포인터는 구조체가 저장되어있는 곳에 매달려 있습니다. .NET에는 좋은 곳이 없으며 스택이나 gc 힙이 없습니다. 구조체를 관리되지 않는 메모리로 명시 적으로 마샬링하지 않는 한. –
@ 한스 : Markus는 객체가 사라진 후에 포인터를 사용하지 않을 정도로 똑똑하다고 생각합니다. 이는 스택 변수에 충분합니다. 그러나 클래스 인스턴스의 멤버에게는 실제로 문제가 있으며이를 언급했습니다. –
@ Hans Uhhh - 감사합니다. 그러나 내 실제 프로젝트에서 필자는 예를 들어 Ben과 같은 하나의 Link 만 반환 할 것입니다. – Markus