【问题标题】:Convert Platform::String to std::string将 Platform::String 转换为 std::string
【发布时间】:2015-02-27 06:52:46
【问题描述】:

我收到String^,它在我的 C++ WinRT 组件中的 C# 组件回调中包含一些印度语言字符,该组件位于 Windows Phone 8 项目的 Cocos2dx 游戏中。

每当我将其转换为std::string 时,印地语和其他字符都会变成垃圾字符。我无法找到发生这种情况的原因。

这是一个示例代码,我刚刚在这里定义了 Platform::String^,但考虑到它是从 C# 组件传递给 C++ WinRT Component

String^ str = L"विकास, વિકાસ, ਵਿਕਾਸ, Vikas";
std::wstring wsstr(str->Data());
std::string res(wsstr.begin(), wsstr.end());

【问题讨论】:

  • 你能把它保留为wstring吗?
  • @PeterTorr-MSFT wstring 内容与String^ 相同,但问题是在将其转换为std::string 时会丢失非英文字符的编码,

标签: c# c++ windows-phone-8 cocos2d-x winrt-component


【解决方案1】:

编辑:请参阅this answer 以获得更好的便携解决方案。

问题在于std::string 仅保存 8 位字符数据,而您的 Platform::String^ 保存 Unicode 数据。 Windows提供函数WideCharToMultiByteMultiByteToWideChar来回转换:

std::string make_string(const std::wstring& wstring)
{
  auto wideData = wstring.c_str();
  int bufferSize = WideCharToMultiByte(CP_UTF8, 0, wideData, -1, nullptr, 0, NULL, NULL);
  auto utf8 = std::make_unique<char[]>(bufferSize);
  if (0 == WideCharToMultiByte(CP_UTF8, 0, wideData, -1, utf8.get(), bufferSize, NULL, NULL))
    throw std::exception("Can't convert string to UTF8");

  return std::string(utf8.get());
}

std::wstring make_wstring(const std::string& string)
{
  auto utf8Data = string.c_str();
  int bufferSize = MultiByteToWideChar(CP_UTF8, 0, utf8Data, -1, nullptr, 0);
  auto wide = std::make_unique<wchar_t[]>(bufferSize);
  if (0 == MultiByteToWideChar(CP_UTF8, 0, utf8Data, -1, wide.get(), bufferSize))
    throw std::exception("Can't convert string to Unicode");

  return std::wstring(wide.get());
}

void Test()
{
  Platform::String^ str = L"विकास, વિકાસ, ਵਿਕਾਸ, Vikas";
  std::wstring wsstr(str->Data());
  auto utf8Str = make_string(wsstr); // UTF8-encoded text
  wsstr = make_wstring(utf8Str); // same as original text
}

【讨论】:

  • 非常感谢 :) std::make_unique 仅适用于 WP 8.1 的通用 C++ 项目,用于像 WP8.0 这样的旧平台我必须使用 char 数组。我找到了一个例子github.com/cocos2d/cocos2d-x/blob/cocos2d-x-2.2.6/extensions/…
  • 一路走标准有什么问题:std::codevect ?
  • @gMorphus,我不知道这一点,所以感谢您的提示(仅供参考,其他人尝试look it upstd::codecvt)。实际上,基于this answer另一个问题更容易。
【解决方案2】:

使用 C++,您可以使用以下代码将 Platform::String 转换为 std::string

Platform::String^ fooRT = "aoeu";
std::wstring fooW(fooRT->Begin());
std::string fooA(fooW.begin(), fooW.end());

参考:How to convert Platform::String to char*?

【讨论】:

  • 这是我找到的最短的前进方式。
  • 这适用于 OP 的示例吗?最后两条语句与问题中的基本相同,会将宽字符截断为8位并丢失信息。
  • 使用 Begin(),而不是 Data()
  • @uliwitness 你是对的,这个解决方案不适用于平台字符串中的 unicode 数据。
猜你喜欢
  • 2016-01-04
  • 2016-01-28
  • 2020-03-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多