まず最初に、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()
を呼び出します。返されたデータは完全に管理されるため、所有権の問題に対処する必要はありません。
動的なタイプのCOM Interopで作業してみましょう。これにより、静的な型指定よりも簡単になり、メモリ管理も容易になります。 – weismat
最後のビットについての参考情報はありますか? C#は既にCOM interopのためのメモリ管理を行い、いつも持っています。動的な型は、例えばIDispatchインタフェースを扱うときに、物事をより簡単にしますが、実際には静的相互運用型とは異なるメモリ管理機能を持っていますか? –