C# _bstr vs“U T” 我有一个.NET库,它被注册为COM对象,当在C++项目中导入.TLB文件时,我得到了这样一个方法声明< /P>
对于.NET等价物C# _bstr vs“U T” 我有一个.NET库,它被注册为COM对象,当在C++项目中导入.TLB文件时,我得到了这样一个方法声明< /P>,c#,c++,com,com-interop,C#,C++,Com,Com Interop,对于.NET等价物 double GetBid(string symbol); 现在我试着这样称呼它 double bid; ptr->GetBid(_T("AAPL"), &bid); 这不符合预期,因为在.NET端,字符串参数实际上是一个空字符串 如果我改打这样的电话 double bid; ptr->GetBid(_bstr_t("AAPL"), &bid); 一切正常 为什么两个调用都编译得很好,但结果不同?第一个调用不应该转换为正确的字符串封送处理吗
double GetBid(string symbol);
现在我试着这样称呼它
double bid;
ptr->GetBid(_T("AAPL"), &bid);
这不符合预期,因为在.NET端,字符串参数实际上是一个空字符串
如果我改打这样的电话
double bid;
ptr->GetBid(_bstr_t("AAPL"), &bid);
一切正常
为什么两个调用都编译得很好,但结果不同?第一个调用不应该转换为正确的字符串封送处理吗
任何关于BSTR magic的秘密信息的Thx:)BSTR在字符串前面有一个32位的长度。因此,BSTR可以包含嵌入的空值
_T(“AAPL”)创建一个wchar_T*,该wchar_T*带有终止null,但没有长度前缀
不过在引擎盖下,两者都是wchar_t*,因此调用可以编译,不需要转换。你有点幸运,因为更糟糕的事情可能会发生,而不仅仅是在另一边没有绳子。封送拆收器可能会查看32位的_T(“AAPL”)倒计时,碰巧得到一个非常长的长度值,这将是不好的。:-)
如果参数被定义为_bstr_t,您将获得自动转换,因为这将调用_bstr_t(wchar_t*)构造函数。bstr在字符串前面有一个32位的长度。因此,BSTR可以包含嵌入的空值
_T(“AAPL”)创建一个wchar_T*,该wchar_T*带有终止null,但没有长度前缀
不过在引擎盖下,两者都是wchar_t*,因此调用可以编译,不需要转换。你有点幸运,因为更糟糕的事情可能会发生,而不仅仅是在另一边没有绳子。封送拆收器可能会查看32位的_T(“AAPL”)倒计时,碰巧得到一个非常长的长度值,这将是不好的。:-)
如果参数被定义为_bstr_t,您将获得自动转换,因为这将调用_bstr_t(wchar_t*)构造函数。因为是指向宽字符串的指针,但这并不意味着您可以只分配简单的常量wchar_t*字符串。要使用BSTR,您需要使用一些系统函数,请参见创建BSTR的第行_bstr_t类包含所有这些内容,因为它是指向宽字符串的指针,但这并不意味着您可以只分配简单的常量wchar_t*字符串。要使用BSTR,您需要使用一些系统函数,请参见创建BSTR的第行_bstr_t类包含所有这些内容简单地说,
wchar*
C字符串不是bstr
。是的,但是当我传递给bstr参数时,它不是由隐式运算符转换的。简单地说,wchar*
C字符串不是bstr
。是的,但是,当我传递给BSTR参数时,隐式运算符不是转换了吗?我想知道为什么Visual Studio在从.tlb生成头文件时不使用_BSTR_t并使用BSTR?它可以,但这取决于在#import语句中使用了什么。您是否仅使用原始接口?是的,我使用了,这里是我使用的#导入“e:\z\ManagedChange\ManagedChange\bin\Debug\ManagedChange.dll.tlb”命名的_guidsraw\u interfaces仅删除raw\u interfaces,它将生成“包装”接口。它们明显不同,而且更容易使用。但它可能会破坏您现有的代码,因为签名是不同的。例如,函数没有返回HRESULT并将返回值设为[out]参数,而是具有实际返回值,并且HRESULT成为异常。它为您提供了其他具有原始名称的签名,允许您访问低级方法。这更好,原始接口也会生成,但有一个前缀raw。我想知道为什么Visual Studio在从.tlb生成头文件时不使用_bstr_t并使用bstr?它可以,但这取决于你在“进口”声明上写了什么。您是否仅使用原始接口?是的,我使用了,这里是我使用的#导入“e:\z\ManagedChange\ManagedChange\bin\Debug\ManagedChange.dll.tlb”命名的_guidsraw\u interfaces仅删除raw\u interfaces,它将生成“包装”接口。它们明显不同,而且更容易使用。但它可能会破坏您现有的代码,因为签名是不同的。例如,函数没有返回HRESULT并将返回值设为[out]参数,而是具有实际返回值,并且HRESULT成为异常。它为您提供了其他带有raw_uu名称的签名,允许您访问低级方法。这更好,还可以生成raw接口,但有一个前缀raw_uu。
double bid;
ptr->GetBid(_bstr_t("AAPL"), &bid);