【问题标题】:CComBSTR memory allocationCComBSTR 内存分配
【发布时间】:2010-12-08 01:03:15
【问题描述】:

我有一个带有很长字符串的“const char* str”。 我需要将它从 cpp 客户端传递给需要 BSTR 类型的 .Net COM 方法。 目前我使用:

CComBSTR bstr = str;

这有以下问题:

  • 有时此行会失败并显示内存不足消息
  • 当我将 bstr 传递给 COM 类时,它会占用大量内存(远远超过字符串大小),因此它可能会因内存不足而失败

问题:

  • 我是否明智地转换为 CComBSTR?例如有没有办法使用堆或其他东西
  • 改用 BSTR 会更好吗?

也欢迎任何其他建议...

【问题讨论】:

    标签: c++ string com out-of-memory


    【解决方案1】:

    如果一个方法期望一个 BSTR 传递一个 BSTR 是唯一正确的方法。

    要将char* 转换为BSTR,请使用MultiByteToWideChar() Win32 API 函数进行转换,使用SysAllocStringLen() 进行内存分配。你无法解决这个问题——你需要SysAllocStringLen() 来分配内存,否则如果调用SysStringLen(),COM 服务器将会失败。

    当您使用CComBSTR 并为其分配char* 时,将运行相同的序列 - ATL 可用作标头,您可以享受阅读它以了解它是如何工作的。所以事实上CComBSTR 做了最少的必要操作。

    当您将 BSTR 传递给 COM 服务器时,会调用 CComBSTR::operator BSTR() const,它只返回一个指向已包装 BSTR 的指针 - BSTR 主体不会被复制。接下来发生的任何事情都取决于 COM 服务器或所使用的互操作 - 他们自己决定是要复制 BSTR 正文还是直接读取它。

    解决内存中断的唯一办法是更改 COM 接口,使其接受一些读取器并通过该读取器请求数据块。

    【讨论】:

      【解决方案2】:

      它是进程内 COM 服务器吗?你有它的代码还是第三方?因为您可以将实际的 char* 指针传递给 COM 服务器,而无需支付 allocate+copy+free 的代价。您将需要添加一个仅对 C++ 客户端可用的新方法/属性。


      您可以将 char* 包装在 Stream 接口中,而不是传递 BSTR,.NET 服务器应该获得 Stream 而不是字符串。

      在 C++ 端实现一个支持IStream COM 接口的 COM 类,该类是包装 char* 的只读流,您可以将该类作为UCOMIStream 接口传递给 .NET 服务器。 在.NET 端使用UCOMIStream 方法读取字符串,注意不要一次读取整个流。

      【讨论】:

      • 我该怎么做?签名显示我需要通过 BSTR。
      • 服务器在.Net,客户端在cpp
      • Stream接口是什么样子的,它也是一个COM接口,那么它在签名中使用哪些类型?
      【解决方案3】:

      CComBSTR 是 BSTR 的包装器,而 BSTR 又被计算为带有特殊终止符的 Unicode 字符串。

      因此,您会期望它的大小大约是相应 char* 形式的两倍(对于主要使用单字节字符的字符集)。

      一般来说,使用 CComBSTR 是一个好主意,因为析构函数会为您释放与 BSTR 关联的内存。

      【讨论】:

      • 问题更多在于将值传递给 COM 对象,那里是否对 BSTR 进行了更多隐式重复?
      猜你喜欢
      • 2021-09-21
      • 2012-08-12
      • 2010-12-17
      • 1970-01-01
      • 1970-01-01
      • 2011-09-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多