c++c++builderunicode-stringc++builder-xe2ansistring

Diffence with AnsiString and AnsiString transfered from UnicodeString in C++ builder


I am using C++ Builder XE3 and I have met a weird problem with AnsiString.

Just look at below code

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

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

Out of my imagine, it works well in the first time, however it throws a "Bad Format" Exception in the second time. And even I just called funcA once with Code 2 the problem remained.

Since it makes no difference when I ShowMessage within temp1 or temp2. I totally can not understand why the two times of call gave me different results.

funcA is from a 3rd library with a little bit complicated code. So before I trace the code of this library I think I should know what the difference is with Code1 and Code2.

Thanks.


Solution

  • As far as funcA() is concerned, there is absolutely no difference whether a char* or a UnicodeString was assigned to the AnsiString. The in-memory representation of the AnsiString data is the same in both cases. So there has to be an issue inside of funcA() itself that is causing the error, regardless of how you prepare the AnsiString. But without knowing what funcA() actually does and what input it expects, there is no way to diagnose this problem. you will have to trace the logic inside of funcA().

    You say funcA() comes from a third-party library. What kind of library is it exactly? Is it a statically linked LIB, or an external DLL/BPL? It makes a big difference. If it is an external DLL/BPL, then you cannot safely pass non-POD data, such as AnsiString, over the DLL boundary unless the DLL/BPL has been compiled with the EXACT SAME compiler, RTL, and Memory Manager as your EXE (in the case of a BPL, that also means enabling Runtime Packages in both BPL and EXE projects). If that is not the case, then it is likely that the DLL/BPL is using a different RTL/MM that interprets the in-memory AnsiString data differently than your EXE does. The in-memory data of an AnsiString was changed in CB2009 to include new fields (namely a codepage and an element size), so if the DLL/BPL was compiled in an earlier compiler version, bad things can happen when it tries to use an AnsiString from your newer compiler (and vice versa).