2011-08-11 16 views
9

私はC++でCOMにAPIを記述しており、このAPIをC#で使用するプログラムも記述しています。私の質問は、BSTRをCOM関数に渡すときのBSTRメモリ管理のセマンティクスに関するものです。私はSomeFunction(myString)のようなものを持つC#からそれを呼び出すと、C#(COM interop)からCOM関数にBSTRを渡すための規約

HRESULT SomeFunction(BSTR input) { 
    // Do stuff ..., then: 
    SysFreeString(input); 
} 

C#この(擬似コード)のようなものが生成されます:現在、この機能は、次のように実装されている

HRESULT SomeFunction([in] BSTR input); 

:私のIDLのように見えると言う

myString = SysAllocString("string"); 
SomeFunction(myString); 
SysFreeString(myString); 
:このような
myString = SysAllocString("string"); 
SomeFunction(myString); 

というか

つまり、C#でCOMインターフェイスにマーシャリングするために生成されたBSTRを解放するか、それを自分の関数内で解放する必要がありますか?ありがとう!

答えて

14

Allocating and Releasing Memory for a BSTRから:

あなたはBSTR引数を受け取る関数を呼び出すとき、あなたは は、呼び出しの前BSTRにメモリを割り当て、 その後、それを解放する必要があります。 ...

入力パラメータであれば解放しないでください。 C#(およびCOMオブジェクトを使用する他のランタイム)は、COMオブジェクトの入出力を管理するためのCOM規則を遵守しなければならず、入力パラメータの場合は文字列のメモリを管理する必要があります。さもなければ、COMオブジェクトはC#または他の言語ランタイムから呼び出されていることをどのように知っていますか?

追加グーグル-FUがこれを上がっ:[中]がが所有しているとして渡さ

  • メモリ:Marshaling between Managed and Unmanaged Code

    ...所有権の問題については、CLRは、COM-スタイル 規則に従います発信者によって割り当てられ、呼び出し元によって解放された
    の両方である必要があります。呼び出し先は、
    そのメモリを解放しないでください。

  • 呼び出し先によって割り当てられ、[out]として渡されたメモリ、または が返されたメモリは、呼び出し元が所有し、呼び出し元によって解放される必要があります。
  • 呼び出し元から[in、out]として渡されたメモリを解放することができます。 は新しいメモリを割り当て、古いポインタ値 を上書きして上書きします。新しいメモリは呼び出し側が所有しています。この には、char **のような2レベルの間接指定が必要です。

interopの世界では、caller/calleeはCLR /ネイティブコードになります。上記の規則 は、固定されていないケースでは、
の場合、CLRの
から[out]としてあなたに渡されたメモリブロックへのポインタを受け取ると、解放する必要があります。一方、CLRがネイティブコードから[out]として渡されるポインタ
を受け取った場合、CLRは
を解放する必要があります。明らかに、最初のケースでは、ネイティブコードは
割り振り解除を行う必要があり、2番目のケースでは、管理コードは
割り振り解除を行う必要があります。

したがって、CLRはメモリ所有権のCOMルールに従います。 QED。

+1

この回答は、CLが自動的にinteropのために行うこととは関係がありません。これはOPが尋ねているすべてのことです。 – ildjarn

+0

@ildjarn:逆に、OPの質問に正確に答えます。 –

+0

@ Alf:間違った理由や間違った文脈やリンクで正解を述べるのは本当に「正しい」わけではありません。 – ildjarn

0

C#開発者またはC++開発者の立場から考えてください。

COM +を扱う場合、C#開発者はメモリ管理について心配する必要はありません。

C++でCOM +コンポーネントを作成すると、呼び出し元がわからなくても、メモリの意味は同じになります。それがパラメータの場合、呼び出し元はC++であろうとC#であろうと、メモリを管理する責任があります。 C#では、CLRがそれを処理します。

関連する問題