我有一个注册为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魔术的任何引擎盖下的信息:)
答案 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类包含了所有这些东西