与C ++构建器中的Unicode字符串传输的AnsiString和AnsiString的区别

时间:2013-01-08 22:58:12

标签: c++ c++builder unicode-string c++builder-xe2 ansistring

我正在使用C ++ Builder XE3,我遇到了AnsiString的一个奇怪的问题。

请看下面的代码

//Code 1: first time
AnsiString temp1 = "test" ;
funcA(temp1,temp1);

//Code 2: second time    
String uTemp2 = "test";
AnsiString temp2 = uTemp2;
funcA(temp2,temp2);

在我的想象中,它在第一次运行良好,但它在第二次抛出“Bad Format”异常。甚至我只是用Code 2调用funcA一次,问题仍然存在。

因为我在temp1或temp2中的ShowMessage时没有任何区别。我完全不明白为什么两次通话给了我不同的结果。

funcA来自第三个库,代码有点复杂。所以在我跟踪这个库的代码之前,我想我应该知道Code1和Code2的区别。

感谢。

2 个答案:

答案 0 :(得分:2)

funcA()而言,将char*UnicodeString分配给AnsiString绝对没有区别。在两种情况下,AnsiString数据的内存中表示都是相同的。因此,无论您如何准备funcA()AnsiString本身内部都会出现导致错误的问题。但是,如果不知道funcA()实际上做了什么以及它期望输入什么,就无法诊断出这个问题。你必须追踪funcA()内的逻辑。

您说funcA()来自第三方库。它到底是什么类型的图书馆?它是静态链接的LIB,还是外部DLL / BPL?它有很大的不同。如果它是外部DLL / BPL,那么除非已使用EXACT SAME编译器,RTL和内存管理器编译DLL / BPL,否则无法安全地在DLL边界上传递非POD数据(如AnsiString)。作为您的EXE(在BPL的情况下,这也意味着在BPL和EXE项目中启用运行时包)。如果不是这种情况,那么DLL / BPL可能正在使用不同的RTL / MM来解释内存中的AnsiString数据,这与EXE不同。在CB2009中更改了AnsiString的内存数据以包括新字段(即代码页和元素大小),因此如果DLL / BPL是在早期编译器版本中编译的,那么当它发生错误时就会发生错误尝试使用新编译器中的AnsiString(反之亦然)。

答案 1 :(得分:0)

我想到的第一件事是,没有来自String构造函数的AnsiString,因此无法将一个String类型分配给AnsiString。你没有提到编译器错误,所以听起来编译器正在为你做一些错误的事情。

此帖子How to convert String to AnsiString提供了一种安全的方式。

基本上你需要在赋值中引用String变量char缓冲区,这样编译器才会做正确的事。

这是older Builder AnsiString reference (1997),提供有关可能的一些构造函数和转换的信息。