관리되지 않는 코드로 Marshal.ptrtoStructure를 통해 마샬링 된 구조를 삭제해야합니까?

StackOverflow https://stackoverflow.com/questions/497133

  •  20-08-2019
  •  | 
  •  

문제

이 C ++ 코드가 있습니다.

extern "C" __declspec(dllexport) VOID AllocateFoo(MY_DATA_STRUCTURE** foo)
{
    *foo = new MY_DATA_STRUCTURE;

    //do stuff to foo
}

그런 다음 C#에서는 기능을 호출합니다.

[DllImport("MyDll.dll")]
static extern void AllocateFoo(out IntPtr pMyDataStruct);

...

MyDataStructure GetMyDataStructure()
{
    IntPtr pData;
    ManagedAllocateFooDelegate(out pData);

    MyDataStructure foo = (MyDataStructure)Marshal.PtrToStructure(pData, typeof(MyDataStructure));
    return foo;
}

MyDatrastructure는 my_data_structure에 해당하는 구조 (클래스가 아님)이며 멤버는 적절하게 마샬링됩니다.

따라서 질문 : PDATA를 저장 한 다음 MYDATASTRUCTURE가 GC'D 일 때 관리되지 않는 코드로 다시 출시해야합니까? MSDN은 Marshal.ptrtostructure (intptr, type)에 대해 다음과 같이 말합니다. 그 문장에서 "Marshall"은 "Copy"를 의미합니까? 어떤 경우에는 (intptr pdata)를 보존 한 다음 MyDatrastructure Destructor에서 관리되지 않는 코드로 전달하여 C ++ "Delete"를 수행 할 수 있습니까?

검색했지만 이것에 대한 충분히 명백한 대답을 찾을 수는 없습니다.

도움이 되었습니까?

해결책

에릭이 말했듯이, 마샬은 사본을 의미하지만, 그가 당신의 질문의 주요 요점에 대답했다고 생각하지 않습니다.

MyDatastructure가 GCE가 될 때까지 PDATA 기본 포인터를 유지해야합니까? 아니.

마샬링되면 MyDattrsucture 인스턴스 FOO에는 PDATA가 가리키는 구조의 사본이 포함되어 있습니다. 더 이상 pdata를 붙잡을 필요가 없습니다. 메모리 누출을 피하려면 해당 PDATA를 관리되지 않는 다른 기능으로 전달해야하며, 마비간 인스턴스를 얼마나 오래 보유하고 있는지에 관계없이 마샬링 직후에 수행 할 수 있습니다.

다른 팁

예,이 경우 Marshall은 사본을 의미합니다. 따라서 관리되지 않는 코드로 메모리를 처리해야합니다. ptrtostructure에 대한 모든 호출은 pdata가 가리키는 메모리 위치에서 'myDatrastructure'의 크기로 표시된 여러 바이트를 읽는 것입니다.

물론 세부 사항은 정확히 'MyDatastructure'의 모습에 달려 있습니다 (MyDattructure에서 FieldOffset 또는 Structlayout 속성을 사용합니까) - 최종 결과는 PtrtoStructure의 수익이 데이터의 사본이라는 것입니다.

처럼 gbegen 지적합니다 그의 대답, 나는 당신의 질문의 요점에 대답하지 않았습니다. 예, 관리되지 않는 코드로 관리되지 않은 구조의 사본을 삭제해야하지만 PDATA를 보류 할 필요는 없습니다. PTRTOSTRSUCTURE 로의 호출이 완료 되 자마자 관리되지 않은 사본을 삭제할 수 있습니다.

추신 : 답변을 하나의 게시물로 통합하기 위해이 정보를 포함하도록 내 게시물을 편집했습니다. 누군가이 답변을 발전 시키면 GBEGEN의 답변과 그의 기여에 대해서도 발전하십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top