tags:

views:

81

answers:

3

Hello!

I am using DelphiIXE.

I learned that GlobalMemoryStatus may return wrong results on 64 computers with more than 4G RAM, so GlobalMemoryStatusex should be used.

But, on the other hand, if I use GlobalMemoryStatusex on 32 computer, the results are wrong on as well (returned numbers are 0 or huge).

Of course I can prepare two programs: one for 64 and one for 32 computers, and use the right memory status, but is there a way to use the same call or recognize that computer is 64? And do something like:

if comp64 then begin GlobalMemoryStatusex .... end else begin GlobalMemoryStatus .... end;

Thanks in advance.

A: 

I think I found the answer:

if sizeof(anypointervariable)>4 then 64bit else 32bit;
Petra
Executables compiled with Delphi XE are still 32-bit, so SizeOf(anypointervariable) will be 4, even if running on 64-bit Windows.
TOndrej
It's possible you are doing something wrong when calling GlobalMemoryStatusEx. Please show the code.
TOndrej
A: 

TOndrej, here is the code:

var MS1:TMemoryStatusex;
    GlobalMemoryStatusex(MS1);
    showmessage('KiloBytes of physical memory: '+FormatFloat('#,###" KB"', MS1.ullTotalPhys / 1024)+chr(10)+
                 'Percent of memory in use: '+Format('%d%%', [MS1.dwMemoryLoad])+chr(10)+
                 'KiloBytes of free physical memory: '+FormatFloat('#,###" KB"', MS1.ullAvailPhys /1024)+chr(10)+chr(10)+
                 'KiloBytes of paging file space: '+FormatFloat('#,###" KB"', MS1.ullTotalPageFile / 1024)+chr(10)+
                 'KiloBytes of free paging file space: '+FormatFloat('#,###" KB"', MS1.ullAvailPageFile / 1024)+chr(10)+chr(10)+
                 'KiloBytes of virtual address space: '+FormatFloat('#,###" KB"', MS1.ullTotalVirtual / 1024)+chr(10)+
                 'KiloBytes of free virtual address space: '+FormatFloat('#,###" KB"', MS1.ullAvailVirtual / 1024) );
Petra
You should edit your question rather than posting it as an answer.
TOndrej
+3  A: 

It seems you are not initializing the structure and you're not checking the return code. Here's a compilable project which should work:

program Project1;

{$APPTYPE CONSOLE}

uses
  Windows,
  Classes,
  SysUtils;

type
  DWORDLONG = UInt64;

  PMemoryStatusEx = ^TMemoryStatusEx;
  TMemoryStatusEx = packed record
    dwLength: DWORD;
    dwMemoryLoad: DWORD;
    ullTotalPhys: DWORDLONG;
    ullAvailPhys: DWORDLONG;
    ullTotalPageFile: DWORDLONG;
    ullAvailPageFile: DWORDLONG;
    ullTotalVirtual: DWORDLONG;
    ullAvailVirtual: DWORDLONG;
    ullAvailExtendedVirtual: DWORDLONG;
  end;

function GlobalMemoryStatusEx(var lpBuffer: TMemoryStatusEx): BOOL; stdcall; external kernel32;

procedure Main;
var
  MemStatus: TMemoryStatusEx;
begin
  // initialize the structure
  FillChar(MemStatus, SizeOf(MemStatus), 0);
  MemStatus.dwLength := SizeOf(MemStatus);
  // check return code for errors
  Win32Check(GlobalMemoryStatusEx(MemStatus));

  Writeln(Format('dwLength: %d', [MemStatus.dwLength]));
  Writeln(Format('dwMemoryLoad: %d', [MemStatus.dwMemoryLoad]));
  Writeln(Format('ullTotalPhys: %d', [MemStatus.ullTotalPhys]));
  Writeln(Format('ullAvailPhys: %d', [MemStatus.ullAvailPhys]));
  Writeln(Format('ullTotalPageFile: %d', [MemStatus.ullTotalPageFile]));
  Writeln(Format('ullAvailPageFile: %d', [MemStatus.ullAvailPageFile]));
  Writeln(Format('ullTotalVirtual: %d', [MemStatus.ullTotalVirtual]));
  Writeln(Format('ullAvailVirtual: %d', [MemStatus.ullAvailVirtual]));
  Writeln(Format('ullAvailExtendedVirtual: %d', [MemStatus.ullAvailExtendedVirtual]));
end;

begin
  try
    Main;
  except
    on E: Exception do
    begin
      ExitCode := 1;
      Writeln(Format('[%s] %s', [E.ClassName, E.Message]));
    end;
  end;
end.
TOndrej
Thanks TOndrej, after adding
Petra
MS.dwLength:=SizeOf(MS); it works fine.
Petra