我正在将旧项目从 C++ Builder 2009 移植到 XE5。在旧项目中,Unicode 字符串的编译器选项设置为“_TCHAR
maps to:char”。这在旧项目中运行良好。
移植时,我在 XE5 中设置了相同的编译器选项。但是对于这样的代码,我仍然会收到编译器错误:
std::string str = String(some_component.Text).t_str();
这会导致以下错误:
所以很明显 XE5 已经决定
String::t_str()
应该给我一个 wchar_t*
而不是 char*
,即使我已经按照上面描述的那样设置了编译器选项。我该如何解决这个问题?
我很清楚 C++ Builder 已经采取了在内部使用 Unicode 的步骤(即使在 2009 版本中),但这是一个具有 200k LOC 的旧项目。将其更新为 Unicode 将是一项非常低优先级的艰巨任务。
编辑
我可以通过将代码更改为
std::string str = AnsiString(some_component.Text).c_str();
但这意味着我必须在很多地方更改代码。有没有不涉及重写代码的更好方法?
最佳答案
当 UnicodeString::t_str()
在 CB2009 中首次引入时,它根据 TCHAR 映射到的内容返回 char*
或 wchar_t*
。为了返回一个 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 是正确且安全的方法。这就是现在的样子。
关于c++ - UnicodeString 兼容性问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21280230/