Как объявить внешнюю функцию, которая существует только на windows 8, не вызывая сбой приложения на windows 7 и ниже? - PullRequest
2 голосов
/ 07 марта 2020

Выглядит глупо, но это способ объявить внешнюю функцию, такую ​​как:

function EnumDynamicTimeZoneInformation(dwIndex: DWORD; lpTimeZoneInformation: PDynamicTimeZoneInformation): DWORD; stdcall; external advapi32;

, потому что, поскольку EnumDynamicTimeZoneInformation доступен только по-прежнему windows 8, это объявление делает приложение cra sh на windows 7 и ниже.

Не удалось найти точку входа в процедуру EnumDynamicTimeZoneInformation в динамической c библиотеке ссылок

. объявление не приведет к сбою приложения, даже если мы не используем его в приложении

Ответы [ 2 ]

4 голосов
/ 07 марта 2020

В Delphi 2010 и более поздних версиях вы можете использовать директиву delayed в конце декларации external, например:

function EnumDynamicTimeZoneInformation(dwIndex: DWORD; lpTimeZoneInformation: PDynamicTimeZoneInformation): DWORD; stdcall; external advapi32 delayed;

Директива delayed может использоваться для оформления внешней подпрограммы, чтобы задержать загрузку библиотеки, содержащей подпрограмму. Фактическая загрузка происходит, когда подпрограмма вызывается в первый раз.

...

Директива delayed полезна в случае, когда импортированные подпрограммы не существуют в целевой операционной системе. система, на которой запущено приложение. Статически импортированные подпрограммы требуют, чтобы операционная система находила и загружала библиотеку при запуске приложения. Если подпрограмма не найдена в загруженной библиотеке или библиотека не существует, операционная система останавливает выполнение приложения. Использование директивы delayed позволяет во время выполнения проверять, поддерживает ли операционная система требуемые API; только тогда вы можете вызвать импортированные подпрограммы.

Например:

if CheckWin32Version(6, 2) then
begin
  EnumDynamicTimeZoneInformation(DesiredIndex);
end;
2 голосов
/ 07 марта 2020

Загрузите библиотеку динамически, затем получите адрес функции.

var
  EnumDynamicTimeZoneInformation : function (dwIndex: DWORD; lpTimeZoneInformation: PDynamicTimeZoneInformation): DWORD; stdcall;
  AdvApiHandle: THandle; 

procedure LoadEnumDynamicTimeZoneInformation()
begin
  if EnumDynamicTimeZoneInformation = nil 
  then begin
    AdvApiHandle := LoadLibrary('advapi32.dll');
    if AdvApiHandle <> 0
    then EnumDynamicTimeZoneInformation := GetProcAddress(AdvApiHandle,'EnumDynamicTimeZoneInformation');    
  end;
end;

begin
  LoadEnumDynamicTimeZoneInformation();
  if EnumDynamicTimeZoneInformation <> nil
  then EnumDynamicTimeZoneInformation(...)
  else ShowMessage('No EnumDynamicTimeZoneInformation');
  ....
  if AdvApiHandle <> 0 
  then FreeLibrary(AdvApiHandle);
end.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...