WOW64 で動作しているかを調べる

 Win32 アプリケーションが WOW64 で動作しているのかどうかを判定するには以下のユニットを利用します。

unit WOW64;

{$IFDEF MSWINDOWS}{$IFDEF WIN32}
{$DEFINE TARGET_WINDOWS}
{$ENDIF}{$ENDIF}

interface

{$IFDEF TARGET_WINDOWS}
uses
  Windows;
{$ENDIF}

function IsWOW64: Boolean;

{$IFDEF TARGET_WINDOWS}
var
  IsWow64Process: function(hProcess: THandle; var Wow64Process: BOOL): BOOL stdcall;
{$ENDIF}

implementation

function IsWOW64: Boolean;
{$IFDEF TARGET_WINDOWS}
var
  Flg: BOOL;
begin
  result := False;
  @IsWow64Process := GetProcAddress(GetModuleHandle('Kernel32.dll'), 'IsWow64Process');
  if @IsWow64Process <> nil then
    if IsWow64Process(GetCurrentProcess, Flg) then
      result := Flg;
{$ELSE}
begin
  result := False;
{$ENDIF}
end;
end.

 WOW64 上で動作していれば IsWOW64() は True を返します。

procedure TForm1.Button1Click(Sender: TObject);
begin
  if IsWOW64 then
    ShowMessage('WOW64')
  else
    ShowMessage('Native Win32');
end;


WOW64 で動作している Win32 アプリケーションに 2GB を超える仮想メモリを割り当てる

 32bit アプリケーションの PE ヘッダフラグに IMAGE_FILE_LARGE_ADDRESS_AWARE を立てると、環境によっては 2GB を超えるメモリを扱う事ができるようになります。

Windows 割り当てられるメモリ空間
Large Address Aware が有効でない 32bit Windows 2GB
Large Address Aware が有効な 32bit Windows < 3GB
64bit Windows (WOW64) 4GB

Large Address Aware が有効な 32bit Windows では 2GB を超える仮想アドレス空間が割り当てられるようになり、WOW64 環境 (64bit Windows) では 4GB の仮想アドレス空間が割り当てられるようになります。

uses
  Windows,
  ...

{$SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE}

 このように *.dpr に記述すると、Large Address Aware 対応アプリケーションにできます。32bit アプリケーションのままでも、64bit OS 上で動作させるメリットを享受できるという事ですね。

 なお、{$SetPEFlags} コンパイラ指令は少なくとも Delphi 7 またはそれ以降で利用可能です。但し、定数が Windows.pas に定義されていない場合があります (64bit Windows 登場以前の環境ですから)。

  IMAGE_FILE_LARGE_ADDRESS_AWARE = $0020;

 但し、このフラグを有効にするには Integer によるポインタ操作をしていない事が条件です。ポインタを Integer でキャストしている場合には正常動作しない可能性があります。

 PE ヘッダのフラグに関する Delphi のトピックとしては DocWiki の "PE (portable executable) header flags (Delphi) (DocWiki)" に詳細があります。


 BACK