代码之家  ›  专栏  ›  技术社区  ›  Eugen

_bstr_r与_T(“”)

  •  0
  • Eugen  · 技术社区  · 10 年前

    我有一个.net库,它注册为COM对象,当在C++项目中导入.tlb文件时,我得到了这样一个方法声明

      virtual HRESULT __stdcall GetBid (
        /*[in]*/ BSTR symbol,
        /*[out,retval]*/ double * pRetVal ) = 0;
    

    对于.NET等效程序

    double GetBid(string symbol);
    

    现在我试着这样称呼它

    double bid;
    ptr->GetBid(_T("AAPL"), &bid);
    

    这并不像预期的那样工作,因为在.NET端,字符串参数实际上是一个空字符串。

    如果我换成这样的电话

    double bid;
    ptr->GetBid(_bstr_t("AAPL"), &bid);
    

    一切都按预期进行。

    为什么两个调用都编译得很好,但结果却不同?第一个调用不应该转换为正确的字符串封送处理吗?

    关于BSTR魔法的任何幕后信息:)

    2 回复  |  直到 10 年前
        1
  •  3
  •   Moby Disk    10 年前

    BSTR具有32位长度 在…之前 字符串。因此,BSTR可以包含嵌入的空值。

    _T(“AAPL”)创建一个wchar_T*,其结尾为null,但没有长度前缀。

    但在幕后,两者都是wchar_t*,因此调用会编译,不需要转换。你有点幸运,因为可能会发生比在另一边没有绳子更糟糕的事情。封送处理程序可能会查看返回32位的_T(“AAPL”)计数,碰巧得到一个非常长的长度值,这将是糟糕的。:-)

    如果将参数定义为_bstr_t,您将获得自动转换,因为这将调用_bstr_t(wchar_t*)构造函数。

        2
  •  1
  •   grisha    10 年前

    因为 BSTR 是一个指向宽字符串的指针,但这并不意味着可以只分配简单的常量wchar*字符串。要使用BSTR,您需要使用一些系统功能 SysAllocString() 用于创建BSTR_bstr_t类封装了所有这些东西