UnicodeString兼容性问题

4

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

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

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

这会导致以下错误:

[bcc32警告] file.cpp(89): W8111 访问已弃用实体 'UnicodeString::t_str() const'

[bcc32错误] file.cpp(89): E2285 无法找到匹配项 'operator string::=(wchar_t *)'

所以显然XE5决定使用wchar_t*而不是char*来提供String::t_str(),即使我已经按照上述说明设置了编译器选项。
如何解决这个问题?
我很清楚C++ Builder已经采取了在内部使用Unicode的步骤(甚至在2009版中),但这是一个有200k行代码的旧项目。将其更新为Unicode将是一项优先级非常低的艰巨任务。 编辑 我可以通过将代码更改为以下内容使其正常工作:
std::string str = AnsiString(some_component.Text).c_str();

但这意味着我必须在许多地方更改代码。是否有更好的方式,而不涉及重写代码?


如果没有其他办法,你可以退而求其次,使用 #define String(a) AnsiString(a)。 - user1233963
1个回答

9
当CB2009首次引入UnicodeString::t_str()时,它根据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是正确且安全的方法。就是现在这样。

好吧,我想我只能使用 AnsiString + c_str() 的方式并重写代码了。仍然有点奇怪的是,C++编译器有一个内部的“String”类型,现在与C++标准字符串完全不兼容。除非C++11或其他版本重新制作std::string以使用wchar_t? - Lundin
1
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类型)。 - Remy Lebeau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接