Объявление внешних функций в зависимости от того, существуют ли они

StackOverflow https://stackoverflow.com/questions/788949

Вопрос

Я хотел бы объявить внешнюю функцию из библиотеки kernel32.dll с именем GetTickCount64.Насколько я знаю, он определяется только в Vista и более поздних версиях Windows.Это означает, что когда я определяю функцию следующим образом:

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

Я определенно не смогу запустить свое приложение в предыдущих версиях Windows из-за ошибки, возникающей при запуске приложения.

Есть ли обходной путь этой проблемы?Допустим, я хотел бы не включать эту функцию, если она не существует, а затем использовать в своем коде какую-нибудь замещающую функцию.Как это сделать?Есть ли какие-нибудь директивы компилятора, которые могли бы помочь?Я предполагаю, что определение должно быть окружено такой директивой, и мне также придется использовать некоторые директивы везде, где я использую функцию GetTickCount64, верно?

Ваша помощь будет оценена по достоинству.Заранее спасибо.

Мариуш.

Это было полезно?

Решение

Объявите указатель на функцию этого типа, а затем загрузите функцию во время выполнения с помощью LoadLibrary или GetModuleHandle и GetProcAddress.Вы можете найти несколько примеров этой техники в исходном коде Delphi;посмотри на TlHelp32.pas, который загружает Библиотека ToolHelp, который недоступен в старых версиях 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;
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top