繁体   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