我有一个注册为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端,string参数实际上是一个空字符串。

如果我改成这样的电话

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


一切都按预期进行。

为什么两个调用都可以正常编译,但是结果却不同?不应将第一个调用转换为正确的字符串封送处理吗?

对于有关BSTR Magic的任何幕后信息,请深表感谢:)

最佳答案

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

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

虽然在后台,这两个都是wchar_t *,所以调用可以编译并且不需要转换。您有些幸运,因为可能发生更糟糕的事情,而不是单枪匹马。封送处理程序可能会查看_T(“ AAPL”)倒计数32位,并且碰巧通过运气获得了一个较长的长度值,这将是不好的。 :-)

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

10-07 17:31