【问题标题】:UnicodeString compatibility issueUnicodeString 兼容性问题
【发布时间】:2014-02-12 08:26:21
【问题描述】:

我正在将一个旧项目从 C++ Builder 2009 移植到 XE5。在旧项目中,Unicode 字符串的编译器选项设置为“_TCHAR 映射到:char”。这在旧项目中运行良好。

移植时,我在 XE5 中设置了相同的编译器选项。但是对于这样的代码,我仍然会遇到编译器错误:

std::string str = String(some_component.Text).t_str();

这会产生以下错误:

[bcc32 警告] file.cpp(89): W8111 Accessing deprecated 实体 'UnicodeString::t_str() const'

[bcc32 错误] file.cpp(89): E2285 找不到匹配项 '操作符字符串::=(wchar_t *)'

显然 XE5 已经决定 String::t_str() 应该给我一个 wchar_t* 而不是 char*,即使我已经如上所述设置了编译器选项。

我该如何解决这个问题?

我很清楚 C++ Builder 已采取步骤在内部使用 Unicode(即使在 2009 版本中),但这是一个具有 200k LOC 的旧项目。将其更新为 Unicode 将是一项艰巨的任务,优先级非常低。

编辑

我可以通过将代码更改为来使其工作

std::string str = AnsiString(some_component.Text).c_str();

但这意味着我必须在很多地方更改代码。有没有更好的不涉及重写代码的方法?

【问题讨论】:

  • 如果没有其他问题,您可以求助于#define String(a) AnsiString(a)

标签: c++ unicode c++builder vcl


【解决方案1】:

UnicodeString::t_str() 在 CB2009 中首次引入时,它返回 char*wchar_t*,具体取决于 TCHAR 映射到的内容。为了返回char*,它改变了 UnicodeString 的内部数据以使其成为 Ansi(从而打破了 UnicodeString 是 Unicode 字符串的约定)。 这是临时的,用于迁移目的,而人们仍在重新编写代码以支持 Unicode。这种破坏是可以接受的,因为 RTL 具有处理 Ansi 编码的 UnicodeString(和 Unicode 编码的 AnsiString)值的特殊逻辑。然而,这是危险的代码。在几个版本之后,当人们有足够的时间进行迁移时,这个 RTL 逻辑被删除了,UnicodeString::t_str() 被锁定为仅wchar_t*,以匹配UnicodeString::c_str()不要再使用t_str()了!这就是它现在被标记为已弃用的原因。如果您需要将 UnicodeString 传递给需要 Ansi 数据的东西,则转换为中间 AnsiString 是正确且安全的方法。这就是现在的样子。

【讨论】:

  • 好吧,我想我只需要将演员阵容滚动到 AnsiString + c_str() 并重写代码。仍然有点奇怪的是,C++ 编译器有一个内部 String 类型,它现在 100% 与 C++ 标准字符串不兼容。除非 C++11 或其他东西重新制作 std::string 以与 wchar_t 一起使用?
  • C++Builder 的 System::StringSystem::CharSystem::PChar 别名的存在是为了与 Delphi 的原生 StringCharPChar 类型兼容。在 CB2009 中,它们分别映射到 UnicodeStringwchar_twchar_t*。在早期版本中,它们映射到 AnsiStringcharchar*。它们与 C++ STL 无关。不同的框架,不同的类型。 STL std::string 类型仍然使用 char。对于wchar_t,请改用std::wstring(C++11 还添加了新的std::u16stringstd::u32string 类型)。
猜你喜欢
  • 1970-01-01
  • 2016-08-28
  • 2011-10-04
  • 2013-03-28
  • 2019-10-03
  • 2018-06-02
  • 2012-03-28
  • 2017-03-31
相关资源
最近更新 更多