fyh*_*ang 9 c# c++ com com-interop
我正在编写用C++编写COM的API,还编写一个在C#中使用这个API的程序.我的问题是关于将BSTR传递给COM函数时的BSTR内存管理语义.说我的IDL看起来像:
HRESULT SomeFunction([in] BSTR input);
Run Code Online (Sandbox Code Playgroud)
目前这个功能是这样实现的:
HRESULT SomeFunction(BSTR input) {
// Do stuff ..., then:
SysFreeString(input);
}
Run Code Online (Sandbox Code Playgroud)
当我用C#调用它时,C#SomeFunction(myString)会生成这样的东西(伪代码):
myString = SysAllocString("string");
SomeFunction(myString);
Run Code Online (Sandbox Code Playgroud)
或者更喜欢这样:
myString = SysAllocString("string");
SomeFunction(myString);
SysFreeString(myString);
Run Code Online (Sandbox Code Playgroud)
也就是说,C#是否释放它生成的BSTR来编组COM接口,还是应该在我的函数中释放它?谢谢!
MSN*_*MSN 15
当您调用需要
BSTR参数的函数时,必须为BSTR调用之前分配内存并在之后释放它....
因此,如果它是输入参数,请不要释放它.C#(以及使用COM对象的任何其他运行时)必须遵守用于管理内存传入和传出COM对象的COM约定,因此必须管理字符串的内存(如果它是输入参数).否则,COM对象如何知道它是从C#或其他语言运行库调用的?
额外的google-fu发现了这一点:托管和非托管代码之间的密钥
...关于所有权问题,CLR遵循COM风格的约定:
- 作为[in]传递的内存由调用者拥有,并且应由调用者
分配并由调用者释放.被调用者不应该
尝试释放或修改该内存.- 被调用者分配并作为[out]传递或返回的内存由调用者拥有,并应由调用者释放.
- 被调用者可以释放作为[in,out]从调用者传递的内存,为其分配新内存,并覆盖旧指针值,从而将其传递出去.新内存由调用者拥有.这需要两个间接级别,例如char**.
在互操作世界中,调用者/被调用者变为CLR /本机代码.上面的规则意味着在未固定的情况下,如果在本机代码中,您
收到一个指向从
CLR 传递给您的内存块的指针,则需要释放它.另一方面,如果CLR收到
一个从本机代码传递为[out]的指针,则CLR需要
释放它.显然,在第一种情况下,本机代码需要进行
解除分配,而在第二种情况下,托管代码需要进行
解除分配.
所以CLR遵循内存所有权的COM规则.QED.
| 归档时间: |
|
| 查看次数: |
3388 次 |
| 最近记录: |