2016-07-19 18 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

関連する問題