2009-04-25 10 views
4

Je voudrais déclarer une fonction externe de la bibliothèque kernel32.dll dont le nom est GetTickCount64. Pour autant que je sache, il est défini uniquement dans Vista et dans les versions ultérieures de Windows. Cela signifie que lorsque je définis la fonction comme suit:Déclarer des fonctions externes selon qu'elles existent

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

Je vais certainement pas en mesure d'exécuter mon application sur les versions précédentes de Windows en raison d'erreur généré au démarrage de l'application.

Y a-t-il une solution de contournement à ce problème? Disons que je voudrais ne pas inclure cette fonction quand elle n'existe pas et ensuite utiliser une fonction de substitution dans mon code. Comment faire ça? Y a-t-il des directives de compilation qui pourraient aider? Je pense que la définition devrait être entourée d'une telle directive et je devrais aussi utiliser certaines directives partout où j'utilise la fonction GetTickCount64, n'est-ce pas?

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

Mariusz.

Répondre

11

déclarer un pointeur de fonction de ce type, puis de charger la fonction lors de l'exécution avec LoadLibrary ou GetModuleHandle et GetProcAddress. Vous pouvez trouver plusieurs exemples de la technique dans le code source Delphi; Regardez TlHelp32.pas, qui charge le ToolHelp library, 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; 
+0

Merci pour votre réponse. Je pense que c'est ce que je cherchais. J'ai une question, cependant. Je voudrais modifier la condition comme suit: sinon Attribué (_GetTickCount64) puis @ _GetTickCount64: = @GetTickCount; Est-ce exact? Comme vous pouvez le voir, j'ai utilisé la fonction GetTickCount qui est déclarée par défaut dans le module "Windows" en tant que substitut lorsque GetTickCount64 n'est pas défini. Je comprends que je peux assigner n'importe quelle fonction qui retourne int64 à la variable _GetTickCount64, non? Ou doit-il être une fonction externe seulement? Je ne connais pas encore le mot clé stdcall :-(. –

+0

Vous pouvez assigner un DWord à un Int64, mais vous ne pouvez pas assigner "pointeur à la fonction retournant DWord" à un "pointeur vers la fonction retournant Int64". Vous pouvez écrire une autre fonction correspondant La signature de GetTickCount64, et dans celle-ci appelez GetTickCount Attribuez un pointeur à la fonction * that * à _GetTickCount64 si vous trouvez la fonction réelle manquante. –

Questions connexes