从 C# 将 BSTR 传递到 COM 函数的约定(COM 互操作)
我正在用 C++ 编写 COM 中的 API,并用 C# 编写一个使用此 API 的程序。我的问题是关于将 BSTR 传递到 COM 函数时的 BSTR 内存管理语义。假设我的 IDL 看起来像这样:
HRESULT SomeFunction([in] BSTR input);
目前这个函数是这样实现的:
HRESULT SomeFunction(BSTR input) {
// Do stuff ..., then:
SysFreeString(input);
}
当我用类似 SomeFunction(myString)
的东西从 C# 调用它时,C# 会生成这样的东西(伪代码):
myString = SysAllocString("string");
SomeFunction(myString);
或者更确切地说是这样的:
myString = SysAllocString("string");
SomeFunction(myString);
SysFreeString(myString);
也就是说,C# 是否释放它生成的 BSTR 以编组到 COM 接口,还是应该在我的函数内释放它?谢谢!
I am writing writing an API in COM in C++, and also writing a program which consumes this API in C#. My question is about BSTR memory management semantics when passing BSTRs into COM functions. Say my IDL looks like:
HRESULT SomeFunction([in] BSTR input);
Currently this function is implemented like this:
HRESULT SomeFunction(BSTR input) {
// Do stuff ..., then:
SysFreeString(input);
}
When I call it from C# with something like SomeFunction(myString)
, will C# generate something like this (pseudocode):
myString = SysAllocString("string");
SomeFunction(myString);
Or rather like this:
myString = SysAllocString("string");
SomeFunction(myString);
SysFreeString(myString);
That is, does C# free the BSTR that it generates to marshal to the COM interface, or should I free it inside my function? Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
来自为 BSTR 分配和释放内存:
所以如果它是输入参数,请不要释放它。 C#(以及使用 COM 对象的任何其他运行时)必须遵守管理 COM 对象内存传入和传出的 COM 约定,因此如果字符串是输入参数,则必须管理该字符串的内存。否则,COM 对象如何知道它是从 C# 或其他语言运行时调用的?
其他 google-fu 出现了这个:托管代码和非托管代码之间的封送处理
因此,CLR 遵循 COM 内存所有权规则。量子ED。
From Allocating and Releasing Memory for a BSTR:
So don't free it if it is an input parameter. 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. Otherwise, how would a COM object know that it is being called from C# or some other language runtime?
Additional google-fu turned up this: Marshaling between Managed and Unmanaged Code
So the CLR follows the COM rules for memory ownership. QED.
您的意思是从 C# 开发人员的角度还是从 C++ 开发人员的角度。
C# 开发人员在处理 COM+ 时不必担心任何内存管理。
在 C++ 中创建 COM+ 组件,您不必知道谁在调用您,内存语义是相同的。如果是 in 参数,则调用者负责管理内存,无论是 C++ 还是 C#。在 C# 中,CLR 会为他们处理这些事情。
Do you mean from the point of view of the C# developer or from the C++ developer.
The C# developer should not have to worry about any memory management when dealing with COM+.
Creating a COM+ component in C++, you would not have to know who is calling you, the memory semantics are the same. If it's an in parameter, the caller is responsible for managing the memory, regardless of whether it's C++ or C#. In C#, the CLR takes care of it for them.