Question

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.

Était-ce utile?

La 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).

Autres conseils

The first thing that came to my mind is that there is not an AnsiString from String constructor so that there is no way to assign a String type to an AnsiString. You do not mention a compiler error so it sounds like the compiler is doing something for you that is the wrong thing.

This posting How to convert String to AnsiString provides a way to do so safely.

Basically you need to reference the String variables char buffer in the assignment so that the compiler will do the right thing.

This is an older Builder AnsiString reference (1997) that provides information about some of the constructors and conversions possible.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top