2016-07-19 4 views
2

C/C# 경계에서 데이터를 마샬링하고 있습니다. 다음과 같이 콜백이 정의콜백 내부에서 IntPtr을 릴리스해야합니까?

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 
public struct Message 
{ 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] 
    public string From; 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] 
    public string Subject; 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] 
    public string Body; 
} 

: 나는 다음과 같은 구조를 가지고

[UnmanagedFunctionPointer(CallingConvention.Cdecl)] 
delegate void MessageReceiveDelegate([In]IntPtr ptrToMessage); 

private void MessageReceiveCallback(IntPtr ptrToMessage) 
{ 
    Message message = (Message)Marshal.PtrToStructure(ptrToMessage, typeof(Message)); 

    Marshal.FreeHGlobal(ptrToMessage); //This throws COMException! 
} 

내 질문에, 나는 메모리 누수를 방지하기 위해 콜백 내부를 IntPtr (ptrToMessage를) 해제에 대해 걱정할 필요합니까입니까? 나는 그것을 FreeHGlobal를 호출하지만, 다음과 같은 예외로 끝날 시도 : 핸들 : 유형 '함께 System.Runtime.InteropServices.COMException'처리되지 않은 예외가 mscorlib.dll

추가 정보 발생

유효하지 않다. ( HRESULT에서 예외 : 0x80070006 (E_HANDLE))

그래서 내가 뭔가 잘못하고 하나 있어요, 또는 메모리 나 발표 할 필요가 없습니다.

+2

코드가 'Intptr'의 소유자가 아닌 경우 (즉, 할당하지 않은 경우) API 문서가 있어야만 코드를 릴리스해야합니다. 'Marshal.FreeCoTaskMem'와 같이 버퍼를 해제하기 위해 다른 Marshal 메소드를 사용해야 할 수도 있습니다. – GreatAndPowerfulOz

+0

@ Great.And.Powerful.Oz IntPtr을 할당하지 않았습니다. 타사 라이브러리에서 나에게 전달되었습니다. 전에 FreeCoTaskMem을 사용해 보았습니다 만, 그 대신에 예외가 발생했습니다. – Eternal21

답변

2

이 메모리는 할당되었습니다. 그렇다면 대부분의 경우 혼자서 배포해야합니다. 없다면 ...

API는 무엇을 사용합니까? 그 기억을 풀어야한다고 말하는가? 할당자가 사용한 것은 무엇입니까? 메모리를 해제하는 방법을 정의합니까? 만약 그렇다면, 당신은 그것을 풀어야합니다. 아니요 ...

아니요, 출시하지 않아야합니다. 예를 들어 스택에 할당 된 구조체에 대한 포인터 일 수 있습니다.

포인터가 있으면 동적으로 할당 된 메모리라는 의미는 아닙니다.

+0

IntPtr을 할당하지 않았습니다. 그것은 콜백의 인수로서 타사 C 라이브러리에서 왔습니다. – Eternal21

+0

@ Eternal21이 라이브러리는 해당 메모리를 해제해야한다고 말합니까? – lorond

+0

아니요, 해당 공급 업체에 문의하려고합니다. – Eternal21

관련 문제