shineworld 73 Posted February 2, 2021 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
David Heffernan 2345 Posted February 2, 2021 Why are you using AnsiString at all? Why aren't you using the string type? Share this post Link to post
shineworld 73 Posted February 2, 2021 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
David Heffernan 2345 Posted February 2, 2021 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
shineworld 73 Posted February 2, 2021 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
David Heffernan 2345 Posted February 2, 2021 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
Arnaud Bouchez 407 Posted February 2, 2021 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
Attila Kovacs 629 Posted February 2, 2021 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