簡體   English   中英

從 C#(COM 互操作)將 BSTR 傳遞到 COM 函數的約定

[英]Convention for passing BSTRs into COM functions from C# (COM interop)

I am writing writing an API in COM in C++, and also writing a program which consumes this API in C#. 我的問題是關於將 BSTR 傳遞到 COM 函數時的 BSTR memory 管理語義。 假設我的 IDL 看起來像:

HRESULT SomeFunction([in] BSTR input);

目前這個 function 是這樣實現的:

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

當我從 C# 用SomeFunction(myString)之類的東西調用它時, C# 會生成類似這樣的東西(偽代碼):

myString = SysAllocString("string");
SomeFunction(myString);

或者更確切地說是這樣的:

myString = SysAllocString("string");
SomeFunction(myString);
SysFreeString(myString);

也就是說,C# 是否釋放它生成的 BSTR 以編組到 COM 接口,還是應該在我的 function 中釋放它? 謝謝!

為 BSTR 分配和釋放 Memory

當您調用需要BSTR參數的 function 時,您必須在調用之前為BSTR分配 memory 並在之后釋放它。 ...

因此,如果它是輸入參數,請不要釋放它。 C# (and any other runtime that uses COM objects) must respect the COM convention for managing memory pass in and out of COM objects, and must therefore manage the memory for the string if it is an input parameter. 否則,COM object 怎么知道它是從 C# 或其他一些語言運行時調用的?

額外的 google-fu 出現了這個:托管和非托管代碼之間的編組

...關於所有權問題,CLR 遵循 COM 風格的約定:

  • 作為 [in] 傳遞的 Memory 歸調用者所有,並且應該是
    由調用者分配並由調用者釋放。 被調用者應該
    不要嘗試釋放或修改 memory。
  • Memory 由被調用者分配並作為 [out] 傳遞或返回,歸調用者所有,應由調用者釋放。
  • 被調用者可以釋放從調用者以 [in, out] 傳遞的 memory,為其分配新的 memory,並覆蓋舊指針值,從而將其傳遞出去。 新的 memory 歸調用者所有。 這需要兩級間接,例如 char **。

在互操作世界中,調用者/被調用者成為 CLR/本機代碼。 上面的規則意味着在未固定的情況下,如果在本機代碼中
從 [out] 接收指向 memory 塊的指針
CLR,你需要釋放它。 另一方面,如果 CLR 收到
從本機代碼作為 [out] 傳遞的指針,CLR 需要
釋放它。 顯然,在第一種情況下,本機代碼需要執行
取消分配,在第二種情況下,托管代碼需要做
取消分配。

因此 CLR 遵循 memory 所有權的 COM 規則。 QED。

您的意思是從 C# 開發人員的角度還是從 C++ 開發人員的角度來看。

C# 開發人員在處理 COM+ 時不必擔心任何 memory 管理。

在 C++ 中創建 COM+ 組件,您不必知道是誰在呼叫您,memory 語義相同。 如果是in參數,則調用者負責管理memory,無論是C++還是C#。 在 C# 中,CLR 會為他們處理。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM