Declarando funções externas, dependendo se eles existem
-
16-09-2019 - |
Pergunta
Gostaria de declarar uma função externa da biblioteca kernel32.dll cujo nome é GetTickCount64. Tanto quanto eu sei, ele é definido apenas no Vista e em versões posteriores do Windows. Isto significa que quando eu definir a função da seguinte forma:
function GetTickCount64: int64; external kernel32 name 'GetTickCount64';
Eu certamente não será capaz de executar o meu aplicativo em versões anteriores do Windows por causa de erro gerado na inicialização do aplicativo.
Existe uma solução para esse problema? Vamos dizer que eu gostaria de não incluir essa função quando ela não existe e, em seguida, usar alguma função substituto no meu código. Como fazer isso? Existem quaisquer diretivas de compilador que iria ajudar? I hóspedes a definição teria que ser cercado por tal directiva e eu também teria que usar algumas directivas onde quer que eu usam o founction GetTickCount64, certo?
A sua ajuda será apreciada. Agradecemos antecipadamente.
Mariusz.
Solução
Declare um ponteiro de função desse tipo, e depois carregar a função em tempo de execução com LoadLibrary
ou GetModuleHandle
e GetProcAddress
. Você pode encontrar vários exemplos da técnica no código fonte Delphi; olhar para TlHelp32.pas , que carrega o biblioteca ToolHelp , que não está disponível em versões anteriores do 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;