2015-11-13 29 views
0

现在我正在做一个Windows Metro应用程序作业,并且正在开发一个C++组件来获取输入方法的候选列表。如何将Bstr转换为Platform :: String?

在最后一步输出结果列表时发生问题。我可以得到候选人列表中的每个成员,但类型是“Bstr”,为了让他们进入Metro应用程序,我必须将它们转换为“Platform :: String”类型。

如何将Bstr转换为Platform :: String?

我真的很感谢您能提供任何帮助。

+0

'BSTR'是一个指向空终止的UTF-16编码的字符串的指针,在指向的字符前面有一个16位(我认为是)字符串长度。根据“Platform :: String”的编码,您可能需要进行一些转换。使用将通过'std :: codecvt'的C++标准库。 –

回答

0

根据MSDN([1][2])我们有这样的定义:

#if !defined(_NATIVE_WCHAR_T_DEFINED) 
typedef unsigned short WCHAR; 
#else 
typedef wchar_t WCHAR; 
#endif 
typedef WCHAR OLECHAR; 
typedef OLECHAR* BSTR; 

所以BSTRwchar_t*型或unsigned short*的,或空值终止的16位字符串。

从我从Platform::String构造函数的文档,请参见接受一个空结束的16位字符串作为const char16*

虽然char16保证代表UTF16,wchar不是。

UPDATE:作为Cheers and hth. - Alf上面的行指出的是不适用于Windows/MSVC如此。在这种情况下,我找不到任何关于两种类型之间是否安全的信息。由于wchar_tchar16_t都是不同的集成类型,我仍然建议使用std::codecvt来避免问题。

所以,你应该用std::codecvtwchar_t*转换为char16_t*,并将结果传递给你Platform::String的构造。

+0

“虽然char16保证代表UTF16,但wchar不是。”这是不正确的:这是在Windows中。 –

+0

@ Cheersandhth.-Alf感谢您指出。我更新了我的答案。 –

1

该平台:: string的构造函数重载使这个非常容易:

BSTR comstr = SysAllocString(L"Hello world"); 
auto wrtstr = ref new Platform::String(comstr); 

是完全完整的,既BSTR和WinRT的字符串可以包含嵌入的0。如果你想处理的那个角落话,那么:

BSTR comstr = SysAllocStringLen(L"Hello\0world", 11); 
auto wrtstr = ref new Platform::String(comstr, SysStringLen(comstr2)); 
+0

你确定将'wchar_t *'强制转换为'char16_t *'是安全的吗?两个('wchar_t'和'char16_t')类型都是不同的内部类型,而不仅仅是另一个类型定义。我找不到任何参考资料表明演员阵容会很安全。 –

+0

这些测试代码片段中没有强制转换。很难弄清楚你可能在谈论什么。对于Unix来说char16_t是必需的,它在Windows上是不相关的。只有一种utf-16编码。 –

+0

也许我在这里完全错了,但是如果你看看我的回答以及我发布的MSDN链接,它可能会变得更清楚我的意思。 'BSTR'是'wchar *',而'Platform :: String'等待'char16 *'。根据[MSDN](https://msdn.microsoft.com/en-us/library/mt228149.aspx)和[cppreference.com'](http://en.cppreference.com/w/cpp/language/)类型)这两种字符类型都表示UTF-16字符,但是是不同的类型。我只想知道这两种类型之间的转换是否安全,因为这两种类型的内部二进制表示可能是不同的(例如不同的补充)。 –

相关问题