将BSTR从C#传递到COM函数的约定(COM互操作) 我在C++中编写了一个API,编写了一个在C语言中使用这个API的程序。我的问题是关于将BSTR传递到COM函数时的BSTR内存管理语义。假设我的IDL看起来像: HRESULT SomeFunction([in] BSTR input);

将BSTR从C#传递到COM函数的约定(COM互操作) 我在C++中编写了一个API,编写了一个在C语言中使用这个API的程序。我的问题是关于将BSTR传递到COM函数时的BSTR内存管理语义。假设我的IDL看起来像: HRESULT SomeFunction([in] BSTR input);,c#,c++,com,com-interop,C#,C++,Com,Com Interop,目前该功能的实现方式如下: HRESULT SomeFunction(BSTR input) { // Do stuff ..., then: SysFreeString(input); } myString = SysAllocString("string"); SomeFunction(myString); SysFreeString(myString); 当我用类似于SomeFunction(myString)的东西从C#调用它时,C#是否会生成类似这样的东西(伪代码)

目前该功能的实现方式如下:

HRESULT SomeFunction(BSTR input) {
    // Do stuff ..., then:
    SysFreeString(input);
}
myString = SysAllocString("string");
SomeFunction(myString);
SysFreeString(myString);
当我用类似于
SomeFunction(myString)
的东西从C#调用它时,C#是否会生成类似这样的东西(伪代码):

或者更确切地说是这样:

HRESULT SomeFunction(BSTR input) {
    // Do stuff ..., then:
    SysFreeString(input);
}
myString = SysAllocString("string");
SomeFunction(myString);
SysFreeString(myString);
也就是说,C#是释放它生成的BSTR以封送到COM接口,还是应该在我的函数中释放它?谢谢

来自:

当您调用需要一个
BSTR
参数的函数时,您 必须在调用之前为BSTR分配内存,并且 之后再释放它

所以,如果它是一个输入参数,就不要释放它。C#(以及任何其他使用COM对象的运行时)必须遵守管理COM对象内存传入和传出的COM约定,因此,如果字符串是输入参数,则必须管理该字符串的内存。否则,COM对象如何知道它是从C#或其他语言运行库调用的

谷歌fu发现了以下内容:

。。。关于所有权问题,CLR遵循COM风格 公约:

  • 作为[in]传递的内存由调用者拥有,并且应该两者都是
    由调用方分配,由调用方释放。被叫方应
    不要试图释放或修改该内存
  • 被调用方分配的内存,作为[out]传递或返回 由调用方拥有,并应由调用方释放
  • 被调用者可以从调用者释放作为[in,out]传递的内存, 为其分配新内存,并覆盖旧指针值, 从而把它分发出去。新内存由调用方拥有。这 需要两个级别的间接寻址,例如char**
在互操作世界中,调用者/被调用者成为CLR/本机代码。规则 以上说明,在未固定的情况下,如果使用本机代码,则

CLR,你需要释放它。另一方面,如果CLR接收到
从本机代码作为[out]传递的指针,CLR需要
释放它。显然,在第一种情况下,本机代码需要执行
取消分配,在第二种情况下,托管代码需要执行
取消分配


因此CLR遵循COM的内存所有权规则。QE.

< P>你是从C开发人员的角度还是从C++开发人员的角度来说明的?br>

C#开发人员在处理COM+时不必担心任何内存管理问题。


在C++中创建COM+组件,您不必知道是谁调用了您,内存语义是相同的。如果它是一个IN参数,则调用方负责管理内存,而不管它是C++还是C语言。在C#中,CLR会为他们处理这些问题。

这个答案与CLR为互操作自动执行的操作无关,而互操作就是关于互操作的所有问题。@Alf:事实上,描述手动COM内存管理的文档与关于CLR可以或不可以代表您执行哪些操作的问题无关。也就是说,问题是关于CLR COM封送的,而这个答案不是。@ildjarn,问题是是否在COM接口中释放参数。答案是否定的,因为CLR使用COM约定作为参数的内存所有权。事实上,这是一个实际的问题:“也就是说,是C#释放它生成的BSTR以封送到COM接口,还是应该在我的函数中释放它?谢谢!”CLR管理通过COM+提供的内存,不是吗?这个问题是关于你在C#中需要做什么。在C#中,是否需要释放out参数?CLR会帮你的,不是吗?如果答案是肯定的,否定的,肯定的-关于CLR和COM+内存管理的评论是无用的,因为它们没有回答关于C#的问题。QEDOk,我是从C#开发者的角度来阅读的,“我应该在我的函数中释放它吗”-不,CLR应该为你做这件事。再次阅读之后,我相信他是在询问他是否应该从C++函数中释放它,这取决于它是从C语言还是C++调用的。如果他真的是这个意思,你的回答很有道理。