Recent

Author Topic: [Solved] 32 Bit vs 64 Bit Question (Compiling "Path Manager" project)  (Read 3271 times)

Peter H

  • Sr. Member
  • ****
  • Posts: 272
Re: 32 Bit vs 64 Bit Question (Compiling "Path Manager" project)
« Reply #15 on: January 21, 2021, 06:40:19 pm »
Ok. Lets agree. Its confusing sometimes. :D

MarkMLl

  • Hero Member
  • *****
  • Posts: 6646
Re: 32 Bit vs 64 Bit Question (Compiling "Path Manager" project)
« Reply #16 on: January 21, 2021, 06:47:45 pm »
So Arg7 is a pointer to a block of memory, not a pointer-to-a-pointer where the size of the referent would depend on whether it's a 32- or 64-bit system.

That means that the function could be defined with either a pointer (typed or untyped) expected at arg 7, or with a var parameter referring to that block of memory: they have very similar behaviour except that a nil parameter can be passed in the former case which has no equivalent in the latter. And I /did/ ask about the declaration rather earlier in the thread.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Peter H

  • Sr. Member
  • ****
  • Posts: 272
Re: 32 Bit vs 64 Bit Question (Compiling "Path Manager" project)
« Reply #17 on: January 21, 2021, 07:13:00 pm »
The Problem is: the meaning of Arg7 can change. This depends from the windows API. The meaning and semantic type of the answer depends from the type of message sent.
So the syntactic types can not tell us the full truth.

This is the prototype that Codetools point me to:
Code: Pascal  [Select][+][-]
  1. function SendMessageTimeout(
  2. hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM; fuFlags, uTimeout: UINT;
  3. var lpdwResult: DWORD_PTR  ): LRESULT;external 'user32' name 'SendMessageTimeoutA';
  4.  

var lpdwResult: DWORD_PTR, this is argument 7
But "@MessageRes" is a constant pointer.
So, why can I give a constant pointer as argument for a var parameter?
There are more prototypes for this function and some would match.
Is Codetools pointing to the wrong polymorphic declaration? (I have seen this before with overloaded functions)
Unfortunately I cannot run this code and see it in debugger, because this would write a new path to the registry or destroy it.

Edit: I tried it anyway and Windows Defender became suspicious and closed lazarus, a program in debugger and manipulating registry hits a breakpoint, defender did not like it  :(
« Last Edit: January 21, 2021, 07:56:51 pm by Peter H »

ASerge

  • Hero Member
  • *****
  • Posts: 2212
Re: 32 Bit vs 64 Bit Question (Compiling "Path Manager" project)
« Reply #18 on: January 21, 2021, 07:43:21 pm »
The Problem is: the meaning of Arg7 can change. This depends from the windows API. The answer depends from the message sent.
So the types can not tell us the full truth.
Yes, the meaning can change, but the size of the variable, which was the question at the beginning, remains constant and equal to SizeOf (DWORD_PTR).

Quote
This is the prototype that Codetools point me to:
Is Codetools pointing to the wrong polymorphic declaration?
The windows.pp unit include the files "ascfun.inc" and "redef.inc". The first describes the last parameter as DWORD_PTR, the second as var DWORD_PTR. Technically, this is the same, since var passes a pointer to a variable.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6646
Re: 32 Bit vs 64 Bit Question (Compiling "Path Manager" project)
« Reply #19 on: January 21, 2021, 07:47:44 pm »
var lpdwResult: DWORD_PTR, this is argument 7
But "@MessageRes" is a constant pointer.
So, why can I give a constant pointer as argument for a var parameter?
There are more prototypes for this fuction and some would match.
Is Codetools pointing to the wrong polymorphic declaration? (I have seen this before with overloaded functions)

I wouldn't like to say what's going on here, and I'm not spending the next few hours refamiliarising myself with the windows API. Sorry :-)

In situations like that that argument would normally contain a pointer (so it can be set null) rather than being passed by address (i.e. a var parameter), and in cases where it might instead contain a scalar (i.e. not a pointer, not a valid address) this would be either a PtrInt or a PtrUInt i.e. something which specifically has the same size as a pointer on the current platform (hence my original suggestion).

That definition that you've given us var lpdwResult: DWORD_PTR might appear misleading due to machine translation, since the combination of Pascal and "Hungarian notation" appears to suggest a pointer-to-a-pointer (var lp) rather than a pointer-to-an-unstructured block (var dwResult).

So it seems to me that that argument could be declared in Pascal as

* var something

* a pointer (typed or untyped)

* a scalar PtrInt or PtrUint

and while the code calling the function would have to make slight adjustment by applying @ and/or a typecast, from the POV of the function being called the parameter would be the same (a sequence of bits the same size as a pointer, which could be translated to the address of a block of memory).

But again I'll happily defer to Somebody with more recent "hands on" of the header translation process etc.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Peter H

  • Sr. Member
  • ****
  • Posts: 272
Re: 32 Bit vs 64 Bit Question (Compiling "Path Manager" project)
« Reply #20 on: January 21, 2021, 08:06:18 pm »
I would say "lpdwResult: DWORD_PTR" means semantically a pointer pointing to a pointer sized memory variable.
If it is really a pointer or reinterpreted as an integer or bitpattern, I do not know it and do not want to know, this could be different from message to message.

Anyway I have given up on this, Windows Defender closed Lazarus and removed it from the taskbar, maybe deleted it (dont know yet) when the program hit a breakpoint, I do not want to deal further with this.
Thanks to all! O:-)
« Last Edit: January 21, 2021, 08:15:58 pm by Peter H »

Peter H

  • Sr. Member
  • ****
  • Posts: 272
Re: [Solved] 32 Bit vs 64 Bit Question (Compiling "Path Manager" project)
« Reply #21 on: January 22, 2021, 01:15:06 am »
I got it working.
The project is from 2013, so I deleted and rebuilt the whole project.
The blue dots were missing, this was solved by setting Debug Symbols explicitely to "Dwarf with sets".
Then it stopped at the breakpoint and in the disassembly I could see, after building the parameter list it calls "SendMessageTimeout" (which is in a windows DLL) directly.

The problem with confusing compiler error messages is: The compiler does not necessarily compile this prototype declaration that is found by searching the declaration of "SendMessageTimeout" in the editor (which uses Codetools so far I know).

It must be added, M$ Windows declares Param No. 7 as "PDWORD_PTR"
"DWORD_PTR" is according to https://docs.microsoft.com/de-de/windows/win32/winprog/windows-data-types?redirectedfrom=MSDN a parameter that is DWORD in 32 Bit WIndows and is expanded to 64 Bit in 64 Bit Windows, so it is always Pointer size, and "PDWORD_PTR" is a pointer to this pointer sized type.
Therefore "@MessageRes" should be always correct in 64 and 32 B´bit, if it points to a pointer sized variable (which is unused by the program, but possibly written by Windows, so the type doesnt matter, only size (and possibly alignment) matters in this case  ;))
However if this is used, the prototype proposed by codetools cannot be used by the compiler, so it must use another prototype which matches and compiles.
BTW, the progam works fine in 32 bit and is not performance critical, so 32 bit is fine, but 64 bit might be needed if snippets of the program are used in 64 bit projects.
« Last Edit: January 22, 2021, 02:26:23 am by Peter H »

Peter H

  • Sr. Member
  • ****
  • Posts: 272
Re: [Solved] 32 Bit vs 64 Bit Question (Compiling "Path Manager" project)
« Reply #22 on: January 22, 2021, 04:28:12 am »
Finally - this solution compiles in 32 Bit and 64 Bit and should be compatible with all compilers, where the windows data types are correctly implemented and is compatible with the prototype which is proposed by codetools:
Code: Pascal  [Select][+][-]
  1. procedure EnvInformation.RefreshEnvironment(const Timeout: Cardinal = 5000);
  2. var
  3.   MessageRes: Windows.DWORD_PTR; // this is a pointer sized variable in Pascal and C/C++
  4. begin                           // So it is a DWORD in 32 Bit and a Quadword in 64 Bit
  5.   Windows.SendMessageTimeout(
  6.     Windows.HWND_BROADCAST,
  7.     Messages.WM_SETTINGCHANGE,
  8.     0,
  9.     LPARAM(PChar('Environment')),
  10.     Windows.SMTO_ABORTIFHUNG, Timeout,
  11.     MessageRes //This is a "var" parameter in Pascal and a const pointer (&MessageRes) in C/C++
  12.   );
  13. end;
« Last Edit: January 22, 2021, 04:54:37 am by Peter H »

PascalDragon

  • Hero Member
  • *****
  • Posts: 5444
  • Compiler Developer
Re: 32 Bit vs 64 Bit Question (Compiling "Path Manager" project)
« Reply #23 on: January 22, 2021, 08:59:43 am »
var lpdwResult: DWORD_PTR, this is argument 7
But "@MessageRes" is a constant pointer.
So, why can I give a constant pointer as argument for a var parameter?
There are more prototypes for this function and some would match.

Yes, there are two overloads as marcov said. The one with var lpdwResult: DWORD_PTR (the one that you found) and the one with lpdwResult: PDWORD_PTR (which I mentioned). If you pass in a DWORD_PTR and not a pointer to a DWORD_PTR then FPC will select the former, otherwise it will select the later.

Peter H

  • Sr. Member
  • ****
  • Posts: 272
Re: [Solved] 32 Bit vs 64 Bit Question (Compiling "Path Manager" project)
« Reply #24 on: January 22, 2021, 03:24:49 pm »
Yes, I tried again.
Now both cases with and without "@" work correctly and are correctly displayed in the editor, when I use code completion or search for the matching declaration of the function prototype.
This did not work correctly before, probably the code tools where confused by these many $IFDEF, which i removed now.

I did not know all this, when I started, and was confused, so thank anybody for all comments and help, finally everything was helpful!
« Last Edit: January 22, 2021, 03:37:27 pm by Peter H »

 

TinyPortal © 2005-2018