2011-11-20 19 views
6

私は、ITaskTrigger :: GetTriggerStringメソッド(http://msdn.microsoft.com/en-us/library/windows/desktop/aa381866(v=vs.85).aspxで定義されています)のピンボケを作成しようとしています。ページを見ると、メソッドの呼び出し元は、最初の引数で参照されるLPWSTRのメモリを(CoTaskMemFree経由で)解放する必要があると言います。 .NETで手動で行うことも、ICustomMarshalerを使用してカスタムマーシャラを作成することもできますが、その特定の引数にMarshalAs(UnmanagedType.LPWStr)属性を使用するとメモリが適切に解放されるかどうかは疑問でした。MarshalAs(UnmanagedType.LPWStr)クリーンアップメモリ​​を使用しますか?

誰かが洞察力を提供できますか?

+0

動的なタイプのCOM Interopで作業してみましょう。これにより、静的な型指定よりも簡単になり、メモリ管理も容易になります。 – weismat

+0

最後のビットについての参考情報はありますか? C#は既にCOM interopのためのメモリ管理を行い、いつも持っています。動的な型は、例えばIDispatchインタフェースを扱うときに、物事をより簡単にしますが、実際には静的相互運用型とは異なるメモリ管理機能を持っていますか? –

答えて

6

まず最初に、COMインターブロック(ITaskTriggerはCOMインターフェイス)であり、P/Invokeではありません。この2つの相互運用ルールには異なるルールがありますので、それらを真っ直ぐに保つことが重要です。たとえば、必要なメソッドだけでなく、インターフェイス全体に対してC#interopラッパーを定義する必要があります。これらはあなたを始めなければなりません:pinvoke.net

短い答えは、CLRがあなたのために適切に世話をする必要があるので、あなたは運がいいです。

長い答えは、パラメータの種類、方向、および相互運用署名に追加する属性に応じて、COM相互運用コードが行うマーシャリングのさまざまなタイプに関係します。

この場合、コールに使用するパラメータのタイプは、MarshalAs(UnmanagedType.LPWSTR)属性の「out string」パラメータです。 COMサーバーがLPWSTR文字列型の "out"パラメータを持つ呼び出しを公開すると、サーバーは取引の終了を維持していると仮定して、CoTaskMemAlloc()というメモリバッファを割り当てて返します。 (BSTRのような異なる文字列タイプの場合は、特定のメモリ割り当て呼び出しが異なる可能性がありますが、基本的な考え方は同じです)。この時点で、不要になったメモリをクリーンアップし、一致するCoTaskMemFree()コールを使用します。

これは「基準変化」と呼ばれる操作の特殊なタイプです:あなたが送信しているパラメータは、すでに参照パラメータですが、COMサーバーが異なる参照してそれを交換に起こっています。このプロセスの良い説明はthis MSDN magazine articleの「メモリ所有権」セクションにあります。この記事からわかるように、CLRは参照型の「out」パラメータからデータを受け取ったときに、そのメモリを解放する責任があると認識します。その呼び出しをマネージコードにマーシャリングしている間に、MarshalAs属性を使用して、これがCOM内のLPWSTR文字列型ポインターであることを確認し、したがってCoTaskMemAlloc()を使用して割り当てられている必要があります。データから管理された文字列を作成した後、あなたの代わりに元のバッファにCoTaskMemFree()を呼び出します。返されたデータは完全に管理されるため、所有権の問題に対処する必要はありません。

+1

答えをありがとう!それは完全にそれを明確にします。 – wwahammy

+1

本当に良い説明、ありがとう。 –

関連する問題