会议传递BSTRs到COM函数从C#(COM互操作) [英] Convention for passing BSTRs into COM functions from C# (COM interop)

查看:176
本文介绍了会议传递BSTRs到COM函数从C#(COM互操作)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写在C ++编写的COM的API,并且还写一个程序,消耗在C#这个API。我的问题是关于BSTR内存管理语义传递BSTRs到COM函数时。说我的IDL看起来像:

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);
}

在我喜欢的东西把它从C# SomeFunction (MyString的),将C#生成像这样(伪):

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);



也就是说,不C#释放它所生成元帅到COM接口BSTR,或者我应该释放它我的函数内部?谢谢!

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!

推荐答案

从的分配并为BSTR 释放内存:

当你调用到期望一个函数的 BSTR 参数,则
必须分配的内存在 BSTR <呼叫,
发布它之后才/ STRONG>。 ...

When you call into a function that expects a BSTR argument, you must allocate the memory for the BSTR before the call and release it afterwards. ...

所以不要释放它,如果它是一个输入参数。 C#(与使用COM对象的任何其他运行时)必须尊重用于管理存储器进出COM对象的COM惯例,因此,必须管理该字符串的存储器,如果它是一个输入参数。 ?否则,一个COM对象怎么会知道它是从C#或其他语言运行时调用

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

...关于所有权的问题时,CLR遵循COM式
约定:

... Regarding ownership issues, the CLR follows COM-style conventions:


  • 内存作为传递[在]被调用者所有,应当由调用者分配和调用者释放这两个结果
    。被叫方应搜索
    不要尝试免费或修改内存。

  • 由被调用方分配和[OUT]传递或返回
    调用者所有,应当由主叫方释放内存。

  • 被叫方可以释放内存从调用者传递[IN,OUT],
    分配新的内存的它,并覆盖旧的指针值,
    从而把出来。新的内存由调用者所有。此
    需要间接两级,如char **。

在互操作的世界,主叫/被叫方变为CLR /本地代码。上述规则
意味着,在非固定的情​​况下,如果在本机代码你结果
获得一个指针,从结果
传递给你的[出]的内存块CLR中,你需要释放它。另一方面,如果在CLR接收结果,
是为[out]从本机代码,在CLR需要搜索
自由它通过一个指针。很明显,在第一种情况下,本机代码需要做的结果,
解除分配和在第二种情况下,托管代码需要做的结果,
解除分配

In the interop world, caller/callee becomes CLR/native code. The rules above imply that in the unpinned case, if when in native code you
receive a pointer to a block of memory passed to you as [out] from
the CLR, you need to free it. On the other hand, if the CLR receives
a pointer that is passed as [out] from native code, the CLR needs to
free it. Clearly, in the first case, native code needs to do the
de-allocation and in the second case, managed code needs to do
de-allocation.

所以CLR遵循内存所有权COM规则。 QED。

So the CLR follows the COM rules for memory ownership. QED.

这篇关于会议传递BSTRs到COM函数从C#(COM互操作)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆