Recent

Author Topic: Lazarus 64 vs Lazarus 32 on Windows  (Read 2670 times)

Nicola Gorlandi

  • Full Member
  • ***
  • Posts: 132
Lazarus 64 vs Lazarus 32 on Windows
« on: October 25, 2022, 07:44:41 am »
Hi all,
I am trying to migrate from Lazarus 32 to Lazarus 64 (both 2.2.4) on Windows.

I have some compiler errors, most of them come from code as below (the error came from l := PCardinal(Cardinal(s) - 4)^; and the error is  Illegal type conversion: "AnsiString" to "LongWord").

By the way, this code is from DIMime library porting from Delphi in Lazarus.

My question is, why on Win32 I do not have such error ?

Many thanks.


Code: Pascal  [Select][+][-]
  1. function MimeEncodeString(const s: AnsiString): AnsiString;
  2. var
  3.   l: Cardinal;
  4. begin
  5.   if Pointer(s) <> nil then
  6.     begin
  7.       l := PCardinal(Cardinal(s) - 4)^;
  8.       SetString(Result, nil, MimeEncodedSize(l));
  9.       MimeEncode(Pointer(s)^, l, Pointer(Result)^);
  10.     end
  11.   else
  12.     Result := '';
  13. end;  
  14.  


PascalDragon

  • Hero Member
  • *****
  • Posts: 5486
  • Compiler Developer
Re: Lazarus 64 vs Lazarus 32 on Windows
« Reply #1 on: October 25, 2022, 07:55:33 am »
My question is, why on Win32 I do not have such error ?

Cardinal has a size of 4 Byte while a Pointer (and thus also a AnsiString) is 8 Byte on 64-bit systems. Thus these are simply not compatible.

Code: Pascal  [Select][+][-]
  1. function MimeEncodeString(const s: AnsiString): AnsiString;
  2. var
  3.   l: Cardinal;
  4. begin
  5.   if Pointer(s) <> nil then
  6.     begin
  7.       l := PCardinal(Cardinal(s) - 4)^;
  8.       SetString(Result, nil, MimeEncodedSize(l));
  9.       MimeEncode(Pointer(s)^, l, Pointer(Result)^);
  10.     end
  11.   else
  12.     Result := '';
  13. end;  
  14.  

Why don't you simply use Length(s)? You gain nothing by doing this yourself except potential for errors (also you should declare your size as SizeInt instead of Cardinal, because the type of the length of a string is platform dependant as well).

ASerge

  • Hero Member
  • *****
  • Posts: 2249
Re: Lazarus 64 vs Lazarus 32 on Windows
« Reply #2 on: October 25, 2022, 06:13:11 pm »
An example version, as the comments specified by @PascalDragon
Code: Pascal  [Select][+][-]
  1. function MimeEncodeString(const S: AnsiString): AnsiString;
  2. var
  3.   InputSize, OutputSize: SizeInt;
  4. begin
  5.   if S <> '' then
  6.   begin
  7.     InputSize := Length(S);
  8.     OutputSize := MimeEncodedSize(InputSize);
  9.     SetString(Result, nil, OutputSize);
  10.     MimeEncode(Pointer(S)^, InputSize, Pointer(Result)^);
  11.   end
  12.   else
  13.     Result := '';
  14. end;

Nicola Gorlandi

  • Full Member
  • ***
  • Posts: 132
Re: Lazarus 64 vs Lazarus 32 on Windows
« Reply #3 on: October 26, 2022, 08:13:12 am »
Many thanks, this solve the issue.

Unfortunately I did not write the procedure, I downloaded somewhere years ago this library in order to code/uncode in base64.

I had already applied your suggestion to another procedure but I am not able to translate this part:
Pointer(Cardinal(Result) + InputSize)^

The function declaration is
function MimeDecodePartialEnd(out OutputBuffer; const ByteBuffer: Cardinal; const ByteBufferSpace: Cardinal): Cardinal;   

I really appreciate your help.

Code: Pascal  [Select][+][-]
  1. function MimeDecodeString(const s: AnsiString): AnsiString;
  2. var
  3.   ByteBuffer, ByteBufferSpace: Cardinal;
  4.   l: Cardinal;
  5.  
  6.  
  7.   InputSize, OutputSize: SizeInt;
  8.  
  9. begin
  10.   if S <> '' then
  11.     begin
  12.       InputSize := Length(S);
  13.       SetString(Result, nil, MimeDecodedSize(InputSize));
  14.       ByteBuffer := 0;
  15.       ByteBufferSpace := 4;
  16.       InputSize := MimeDecodePartial(Pointer(s)^, InputSize, Pointer(Result)^, ByteBuffer, ByteBufferSpace);
  17.       Inc(InputSize, MimeDecodePartialEnd(Pointer(Cardinal(Result) + InputSize)^, ByteBuffer, ByteBufferSpace));
  18.       SetLength(Result, InputSize);
  19.     end
  20.   else
  21.     Result := '';
  22. end;  
  23.  
  24.  

Nicola Gorlandi

  • Full Member
  • ***
  • Posts: 132
Re: Lazarus 64 vs Lazarus 32 on Windows
« Reply #4 on: October 26, 2022, 08:15:46 am »
Sorry I forgot a questiont: is it possible that Lazarus have a library to code / decode in base64 that I can use ?

many thanks again

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Lazarus 64 vs Lazarus 32 on Windows
« Reply #5 on: October 26, 2022, 08:33:13 am »
Not Lazarus, but FPC.
Code: Pascal  [Select][+][-]
  1. uses  base64, ...

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2090
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Lazarus 64 vs Lazarus 32 on Windows
« Reply #6 on: October 26, 2022, 10:02:06 am »
Not Lazarus, but FPC.
Code: Pascal  [Select][+][-]
  1. uses  base64, ...
Just for completition
https://www.freepascal.org/docs-html/current/fcl/base64/encodestringbase64.html
https://www.freepascal.org/docs-html/current/fcl/base64/decodestringbase64.html
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

PascalDragon

  • Hero Member
  • *****
  • Posts: 5486
  • Compiler Developer
Re: Lazarus 64 vs Lazarus 32 on Windows
« Reply #7 on: October 27, 2022, 07:32:53 am »
I had already applied your suggestion to another procedure but I am not able to translate this part:
Pointer(Cardinal(Result) + InputSize)^

Judging by the context you posted I'd use Pointer(@Result[InputSize + 1])^ or - to keep closer to the original code - Pointer(PtrUInt(Result) + InputSize)^.

Nicola Gorlandi

  • Full Member
  • ***
  • Posts: 132
Re: Lazarus 64 vs Lazarus 32 on Windows
« Reply #8 on: October 30, 2022, 10:29:54 am »
Many thanks to everybody, at the end I choose to use the base64 unit in FPC.

 

TinyPortal © 2005-2018