【问题标题】:Should there be a difference between an empty BSTR and a NULL BSTR?空 BSTR 和 NULL BSTR 之间应该有区别吗?
【发布时间】:2010-09-15 08:36:17
【问题描述】:

在维护COM 接口时,空的BSTR 是否应该以与NULL 相同的方式处理? 换句话说,这两个函数调用应该产生相同的结果吗?

 // Empty BSTR
 CComBSTR empty(L""); // Or SysAllocString(L"")
 someObj->Foo(empty);

 // NULL BSTR
 someObj->Foo(NULL);     

【问题讨论】:

    标签: com string bstr


    【解决方案1】:

    是的 - NULL BSTR 与空 BSTR 相同。我记得当我们从 VS6 切换到 2003 时,我们发现了各种各样的错误 - CComBSTR 类对使用 NULL 而不是空字符串分配它的默认构造函数进行了更改。例如,当您将 BSTR 视为常规 C 样式字符串并将其传递给诸如 strlen 之类的函数,或尝试使用它初始化 std::string 时,就会发生这种情况。

    Eric Lippert 在Eric's Complete Guide To BSTR Semantics 中详细讨论了 BSTR:

    让我先列出差异,然后 然后讨论中的每一点 令人痛苦的细节。

    1. BSTR 必须具有相同的 NULL 和 "" 的语义。一个 PWSZ 经常有不同的语义 那些。

    2. 必须分配和释放 BSTR 与 SysAlloc* 系列 职能。 PWSZ 可以是 从自动存储缓冲区 堆栈或使用 malloc、new、 LocalAlloc 或任何其他内存 分配器。

    3. BSTR 是固定长度的。一个 PWSZ 可以是任意长度,仅受以下限制 它的有效内存量 缓冲区。

    4. BSTR 总是指向第一个 缓冲区中的有效字符。一个 PWSZ 可能是指向中间或结尾的指针 字符串缓冲区。

    5. 在分配 n 字节 BSTR 时,您 有空间容纳 n/2 个宽字符。 当您为 PWSZ 分配 n 个字节时 您可以存储 n / 2 - 1 个字符 -- 你必须为空值留出空间。

    6. BSTR 可以包含任何 Unicode 数据 包括零字符。一个 PWSZ 从不包含零字符 除了作为字符串结束标记。 BSTR 和 PWSZ 总是有一个 最后一个有效字符后的零字符 字符,但在 BSTR 中是有效的 字符可能是零字符。

    7. BSTR 实际上可能包含一个奇数 字节数——它可以用于 移动二进制数据。 PWSZ 是 几乎总是偶数字节 并且仅用于存储 Unicode 字符串。

    【讨论】:

    • 在紧握的手上---我经历过不遵守 NULL == 空规则的 MSXML 代码,并且两者表现出不同的行为。但那是 5 年前的事了(如果我没记错的话,是 MSXML 3),希望他们现在已经解决了这个问题。 :-)
    • .NET 互操作也不遵守规则 - 它们将 "" 编组为 String.Empty 并将 NULL 编组为 null。
    • 技术上它们不同。是否将空值作为空字符串处理取决于实现。见msdn.microsoft.com/en-us/library/cc237580.aspx
    【解决方案2】:

    处理这种困境的最简单方法是使用 CComBSTR 并检查 .Length() 是否为零。这适用于空值和 NULL 值。

    但是,请记住,必须释放空的 BSTR,否则会出现内存泄漏。我最近在其他人的代码中看到了其中的一些。如果不仔细看的话,很难找到。

    【讨论】:

      猜你喜欢
      • 2010-09-25
      • 1970-01-01
      • 2013-06-13
      • 2023-03-27
      • 2012-09-19
      • 1970-01-01
      • 2014-09-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多