Search code examples
delphidelphi-xe5

How to call GetProcessAffinityMask from Delphi XE5


I tried to use the below code snippet to call GetProcessAffinityMask in the windows api.

var 
  procaffmask, 
  sysaffmask       : DWord;
begin
  GetProcessAffinityMask(GetCurrentProcess, procaffmask, sysaffmask);
end;

Upon compilation I got the following error message......

[dcc32 Error] UnitfrmMain.pas(54): E2033 Types of actual and formal var parameters must be identical

The C++ syntax for the API call is below:

BOOL WINAPI GetProcessAffinityMask(
  _In_  HANDLE     hProcess,
  _Out_ PDWORD_PTR lpProcessAffinityMask,
  _Out_ PDWORD_PTR lpSystemAffinityMask
);

So then I changed the DWORD to a PDWORD but that did not fix it.

Can anybody tell me how to fix this? I see Delphi code samples around the internet that do not use pointers.


Solution

  • Here is the declaration of GetProcessAffinityMask() in Delphi's Winapi.Windows unit:

    function GetProcessAffinityMask(hProcess: THandle;
      var lpProcessAffinityMask, lpSystemAffinityMask: DWORD_PTR): BOOL; stdcall;
    

    DWORD and DWORD_PTR are different data types. DWORD_PTR is not a "pointer to a DWORD", it is actually a "pointer-sized DWORD" (4 bytes on a 32bit system, 8 bytes on a 64bit system). Whereas DWORD is always 4 bytes on both 32bit and 64bit systems. Microsoft uses the P prefix to indicate a pointer to a type, and uses the _PTR suffix to indicate the type itself is dependent on the byte size of a pointer.

    The Delphi declaration is using var parameters, so you have to match the data type exactly:

    var 
      procaffmask, 
      sysaffmask       : DWORD_PTR;
    begin
      GetProcessAffinityMask(GetCurrentProcess, procaffmask, sysaffmask);
    end;
    

    Even your quote of the C++ declaration shows that the parameters are PDWORD_PTR (pointer to DWORD_PTR).