Declaración de funciones externas en función de si existen
-
16-09-2019 - |
Pregunta
Me gustaría declarar una función externa de la biblioteca kernel32.dll cuyo nombre es GetTickCount64. Por lo que yo sé, se define sólo en Vista y en versiones posteriores de Windows. Esto significa que cuando defino la función como sigue:
function GetTickCount64: int64; external kernel32 name 'GetTickCount64';
Yo desde luego no ser capaz de ejecutar mi aplicación en versiones anteriores de Windows debido a errores generados al iniciar la aplicación.
¿Hay una solución a este problema? Digamos que me gustaría no incluir esa función cuando no existe y luego utilizar algunas funciones de suplencia en mi código. ¿Como hacer eso? ¿Hay directivas del compilador que ayudarían? Me gues la definición tendría que estar rodeado de dicha directiva y yo también tendría que usar algunas directivas donde quiera que utilizo el founction GetTickCount64, ¿verdad?
Se observará su ayuda. Gracias de antemano.
Mariusz.
Solución
Declarar un puntero de función de ese tipo, y luego cargar la función en tiempo de ejecución con LoadLibrary
o GetModuleHandle
y GetProcAddress
. Usted puede encontrar varios ejemplos de la técnica en el código fuente de Delphi; mirar a TlHelp32.pas , que carga el href="http://msdn.microsoft.com/en-us/library/ms686837.aspx" rel="nofollow noreferrer"> biblioteca , que no está disponible en versiones anteriores 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;