我正在移植一个非常旧的Builder副本(>15年(中的一些代码。在那些日子里,各种控件的Text属性都属于AnsiString
类型。在最新版本的C++Builder中,情况似乎不再如此。数据类型是什么?
我能从帮助中得到的只是TCaption
,这是一种类型吗?
我的代码编译并运行,但在尝试使用简单的编辑框时,文本不是键入的内容,通常是"0"。c_str()
起作用,但给出了错误的值。
C++Builder的RTL和VCL框架使用的默认字符串类型一直是Delphi当时的原生String
类型。像TCaption
、TFileName
等只是String
的别名(但它们附加了不同的RTTI,以便IDE的对象检查器可以区分它们(。
Delphi的String
类型是Delphi原生Char
类型元素的容器。
C++Builder提供System::Char
和System::String
别名以匹配Delphi的原生Char
和String
类型:
-
在C++Builder 2007及更早版本中,Delphi的原生
Char
类型为AnsiChar
,因此System::Char
是C/C++的char
的别名,System::String
是System::AnsiString
的别名。因此,System::String
是一个8位ANSI字符串,而String::c_str()
返回了一个以null结尾的char*
指针。 -
在C++Builder 2009及更高版本中,Delphi的原生
Char
类型是WideChar
,因此System::Char
现在是Windows上wchar_t
和POSIX上char16_t
的别名,System::String
现在是System::UnicodeString
的别名。因此,System::String
是一个16位UTF-16字符串,而String::c_str()
分别返回一个空终止的wchar_t*
/char16_t*
指针。
因此,任何在C样式字符串指针上操作的代码,而不是使用在System::String
上操作的RTL功能,都必须相应地更新,才能从ANSI移动到UTF-16。
请参阅Embarcadero的Unicode迁移在线资源。转换对于Delphi用户来说是透明的,但对于C++用户来说,它往往需要更多的工作。
我认为您必须将代码迁移到Unicode。首先熟悉下一个资源:
- C++编译器和Unicodehttps://community.embarcadero.com/index.php/blogs/entry/cbuilder-and-unicode-43342
- 将C++Builder项目迁移到Unicode:https://www.youtube.com/watch?v=H-KFq5M0z0A&feature=emb_logo
- 迁移和升级中心:https://www.embarcadero.com/rad-in-action/migration-upgrade-center
祝好运
[免责声明]
全部"代码示例";这些都是我的想法,并没有真正编译
String
类型只是根据UNICODE
定义选择AnsiString
或UnicodeString
类的宏。
早些时候,默认情况下没有定义UNICODE
,因此使用了char
,选择了AnsiString
类。现在默认情况下定义了UNICODE
,因此使用wchar_t
,选择UnicodeString
类。这非常方便,因为Windows API现在默认为Unicode。
还有其他几种类型,如WideString
、UTF8String
等。它们都有大致相同的接口(因此可以互换(。因此,.c_str()
根据所选择的String
类返回不同的类型。
要迁移,通常只需在所有常量字符串前面放一个L
,例如L"My unicode message"
应该只有在极少数情况下,您特别需要8位char
。对于这些情况,您可以使用AnsiString()
进行转换。
String Foo = "This is Unicode";
Bar(AnsiString(Foo).c_str()); // AnsiString converts Foo into an 8bit char pointer.
Baz(Foo.c_str()); // Foo returns a wchar_t pointer.
Windows API通常每个函数有两个版本,对于Ansi为xxxxA,对于宽版本为xxxxW。如果省略结尾的A
或W
,Windows将根据UNICODE
的定义使用正确的版本。W版本要求您使用L"My string"
,而A版本则不需要。微软用TEXT
宏解决了这个问题:TEXT("Auto converted")
。TEXT
宏将根据UNICODE
的定义将常量字符串转换为ansi或wide。通过选择正确的API函数版本,此行将正确使用已定义或未定义的UNICODE
。
MessageBox(TEXT("Auto converted string"),TEXT("TEXT MACRO"),0);
通过将A或W附加到API函数名,可以强制Windows使用Ansi或Wide版本。
MessageBoxA("This is the ansi version","MessageBoxA",0);
MessageBoxW(L"This is the wide version",L"MessageBoxW",0);
如果可能的话,我建议您将项目迁移为仅使用String
,如果绝对需要,则转换为AnsiString
(例如调用仅接受8位char
的库函数(。在您的项目中,默认情况下char
应为wchar_t
(请参阅"项目-选项-C++共享选项-_TCHAR映射到"(