delphi64-bitgetprocaddress

GetProcAddress fails to run when compiled under Delphi XE6 x64


The following GetProcAddress code fails when compiled under Delphi XE6 x64. It runs fine when compiled under Delphi x86. Could you help to comment what is done wrong ?

program Project11;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  SysUtils;

var
  Library_OpenGL: LongWord;

function LoadLibrary(lpFileName: pAnsiChar): LongWord; stdcall; external 'kernel32.dll' name 'LoadLibraryA';
function GetProcAddress(hModule: LongWord; lpProcName: pAnsiChar): Pointer; stdcall; external 'kernel32.dll' name 'GetProcAddress';

begin
  try
    Library_OpenGL := LoadLibrary('opengl32.dll');
    Assert(GetProcAddress(Library_OpenGL, 'glEnable') <> nil, 'GetProcAddress(Library_OpenGL, ''glEnable'') = nil');
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  ReadLn;
end.

Solution

  • Your translations are wrong. A module handle is pointer sized which explains why your erroneous translations worked on 32 bit but not 64 bit.

    To correct, add the Windows unit to your uses clause, remove your declarations of LoadLibrary() and GetProcAddress(), and declare Library_OpenGL as HMODULE (which is 8 bytes in x64):

    program Project11;
    
    {$APPTYPE CONSOLE}
    
    {$R *.res}
    
    uses
      SysUtils, Windows;
    
    var
      Library_OpenGL: HMODULE;
    
    begin
      try
        Library_OpenGL := LoadLibrary('opengl32.dll');
        Assert(GetProcAddress(Library_OpenGL, 'glEnable') <> nil, 'GetProcAddress(Library_OpenGL, ''glEnable'') = nil');
      except
        on E: Exception do
          Writeln(E.ClassName, ': ', E.Message);
      end;
      ReadLn;
    end.
    

    As an added benefit you now call the native Unicode LoadLibraryW directly rather than going via the LoadLibraryA adapter with its conversation from ANSI to the system native UTF-16.