_bstr_r vs _T("")

时间:2014-07-30 18:56:48

标签: c# c++ com com-interop

我有一个注册为COM对象的.net库,在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 个答案:

答案 0 :(得分:3)

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

_T(“AAPL”)创建一个wchar_t *,其终止为null,但没有长度前缀。

虽然在引擎盖下,两者都是wchar_t *所以调用编译并且不需要转换。你有点幸运,因为更糟糕的事情可能发生,而不是在另一边没有字符串。编组人员可能会将_T(“AAPL”)计数看回32位,并且恰好通过运气得到一个长度长的值,这将是不好的。 : - )

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

答案 1 :(得分:1)

因为BSTR是指向宽字符串的指针,但这并不意味着你可以只分配简单的const wchar_t * string。要使用BSTR,您需要使用一些系统函数,行SysAllocString()来创建BSTR。 _bstr_t类包含了所有这些东西