Jump to content
Sign in to follow this  
shineworld

AnsiPos and AnsiString

Recommended Posts

Hi all.

I'm getting crazy with old software (Delphi 2006) port to Sydney about AnsiPos of an AnsiString:
 

function TTCPBin01.GetTargetAnswer: AnsiString;
begin
  Result := FTargetAnswer;
end;

..
..

  if AnsiPos('?y', GetTargetAnswer) <> 0 then
  begin
    FErrorCode := sigc_None;
    FErrorMessage := SignalMessage(FErrorCode);
    Result := qmct_Prog;
  end

GetTargetAnswer return an AnsiString.
Also using AnsiPos to check for a substring in the resulting string the compiler notice me:
[dcc32 Warning] osTCPBin01.pas(224): W1057 Implicit string cast from 'AnsiString' to 'string'.

Placing the mouse cursor on AnsiPos the HINT some time notice me:

function (const SubStr: string; const S: string): Integer;

 

Other times notice me:

 

function (const SubStr: AnsiString; const S: AnsiString): Integer;

 

In either case however the compiler notice Implicit cast...

Have you any suggestion about?

Best regards
Silverio Diquigiovanni

 

Share this post


Link to post

I've moved almost all software from (Ansi)string of BDS2006 to string of Sydney.

 

This is a little part of TCP connection to our embedded boards which uses old (Ansi)string and I just would to keep it as is, because works

and is a little bit complicated; access to return strings as array of bytes for many algorithms (crypt, compressing, CRC, hashing, etc.).

Share this post


Link to post

AnsiString is no longer like an array of bytes because of the implicit encoding conversions that happen with that type. If you really have byte array data then perhaps a byte array is what you need. 

Share this post


Link to post

You are right!
I will move all to arrays of bytes.
Unfortunately, a lot of old functions assumed a string as an array of chars sometimes cast to bytes. 
I need to change the entire set of them, it's the only valid solution.

Share this post


Link to post

Take some time to find/write helper functions to do the sort of processing you need on these byte arrays and your code may even end up easier to read! 

Share this post


Link to post

1. Use RawByteString instead of AnsiString if you don't want to force any conversion.

2. Note that Ansi*() functions are not all meant to deal with AnsiString, but they expect string/UnicodeString types, and deal with current system locale e.g. for comparison or case folding...
A bit confusing indeed...

 

3. Consider using your own version of functions- as we did with https://github.com/synopse/mORMot2/blob/master/src/core/mormot.core.base.pas - so you are sure there is no hidden conversion.

 

4. The main trick is indeed to never let any 'Implicit string cast' warning unfixed.
And sometimes use Alt+F2 to see the generated asm, and check there is no hidden "call" during the conversion.

 

5. Another good idea is to write some unit tests of your core process, uncoupled from TCP itself: write them in the original pre-Unicode Delphi, then recompile the code with the Unicode version of Delphi and ensure they do pass.
It will save you a lot of time!

 

 

Share this post


Link to post
2 hours ago, shineworld said:

Placing the mouse cursor on AnsiPos the HINT some time notice me:
function (const SubStr: string; const S: string): Integer;

Other times notice me:

function (const SubStr: AnsiString; const S: AnsiString): Integer;

 

to answer your original question:

 

They are in different units, one in System.AnsiStrings the other in System.SysUtils, and either you are using them mixed or they are declared in random order in the uses list. 

 

 

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×