4 votes

Déclarer des fonctions externes selon qu'elles existent ou non

Je voudrais déclarer une fonction externe de la bibliothèque kernel32.dll dont le nom est GetTickCount64. Pour autant que je sache, cette fonction n'est définie que dans Vista et dans les versions ultérieures de Windows. Cela signifie que lorsque je définis la fonction comme suit :

function GetTickCount64: int64; external kernel32 name 'GetTickCount64';

Je ne pourrai certainement pas faire fonctionner mon application sur les versions précédentes de Windows à cause d'une erreur générée au démarrage de l'application.

Existe-t-il une solution à ce problème ? Disons que j'aimerais ne pas inclure cette fonction lorsqu'elle n'existe pas et utiliser une fonction de substitution dans mon code. Comment faire ? Existe-t-il des directives du compilateur qui pourraient aider ? Je suppose que la définition devrait être entourée d'une telle directive et que je devrais également utiliser des directives chaque fois que j'utilise la fonction GetTickCount64, n'est-ce pas ?

Votre aide sera appréciée. Merci d'avance.

Mariusz.

12voto

Rob Kennedy Points 107381

Déclarez un pointeur de fonction de ce type, puis chargez la fonction au moment de l'exécution avec LoadLibrary o GetModuleHandle y GetProcAddress . Vous trouverez plusieurs exemples de cette technique dans le code source de Delphi. TlHelp32.pas qui charge le fichier Bibliothèque ToolHelp qui n'est pas disponible sur les anciennes versions de Windows NT.

interface

function GetTickCount64: Int64;

implementation

uses Windows, SysUtils;

type
   // Don't forget stdcall for API functions.
  TGetTickCount64 = function: Int64; stdcall;

var
  _GetTickCount64: TGetTickCount64;

// Load the Vista function if available, and call it.
// Raise EOSError if the function isn't available.
function GetTickCount64: Int64;
var
  kernel32: HModule;
begin
  if not Assigned(_GetTickCount64) then begin
    // Kernel32 is always loaded already, so use GetModuleHandle
    // instead of LoadLibrary
    kernel32 := GetModuleHandle('kernel32');
    if kernel32 = 0 then
      RaiseLastOSError;
    @_GetTickCount := GetProcAddress(kernel32, 'GetTickCount64');
    if not Assigned(_GetTickCount64) then
      RaiseLastOSError;
  end;
  Result := _GetTickCount64;
end;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X