скрыть

скрыть

  Форум  

Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



Google  
 

Динамическое использование DLL



Автор: Dr. Bob

Y3K. На пляже мама с ребенком.
- Мам, а откуда берется песок?
- Из микросхем. Их сердцевина состоит из кремния. Его собирают, перемалывают и сжигают, и получают песок.

...возможно ли заставить Delphi осуществлять только линковку ссылок на необходимые приложению DLL-функции с помощью директив компилятора или чего-то подобного? Я могу с ними динамически связаться с помощью GetProcAddress или функций линковки, но я был бы счастлив если была бы альтернатива попроще. (стилистика авторская - В.О.)

Нет, даже в вашем случае вы должны использовать динамическое связывание...

Часто кажется, что проще написать в модуле явное импортирование функций, чем использовать их динамическое связывание. Тем не менее, основное преимущество динамически загружаемых DLL в том, что ваше приложение может быть загружено и быть работоспособным и в случае отсутствия DLL, при условии, что приложение может к этому "приспособиться". Например, если если вы реализовали в своей DLL трехмерное представление вашего объекта, но DLL не была найдена (при попытке загрузить ее динамически), то приложение также будет работать, но объекты будут представлены в обычном, двумерном виде. Если DLL, о которой идет речь, будет связана статически, Windows откажется выполнять приложение (с претензией, что ваша 3D.DLL не была обнаружена), чему пользователь будет "неслыханно рад". Другое преимущество явного импорта в модуле в том, что приложение будет загружаться быстрее, поскольку динамически подгружаемые DLL будут загружены впоследствии, когда они действительно понадобятся.

Проследим, что получается, если вы используете в модуле явный импорт DLL или в вашем коде вы объявляете функцию DLL с внешним 'DLLNAME'. В этом случае компоновщик установит ссылки на DLL-функции в таблице импортируемых имен скомпонованного EXE-файла и загрузчик Windows автоматически загрузит DLL (во время выполнения главного блока) вместе с файлом EXE:


procedure Foo(X: Integer); external 'BAR' index 1;

Если в течение связывания (также называемое статической линковкой) Windows не сможет найти DLL, вы получите предупреждение - чаще всего File Error MessageBox (как раз то, в котором не указан ненайденный файл - ну очень "полезная" штуковина!). Поэтому вы должны быть абсолютно уверенными в том, что DLL будет доступна все то время, когда вы захотите ей воспользоваться, т.е. всегда.

Динамически связанная DLL, использующая модуль явного импорта, пользуется методами VB, каковые вы также можете использовать, но делая это "вручную". С помощью LoadLibrary по мере необходимости вы загружаете DLL, получаете указатели на экспортируемые функции, которые вы предполагаете использовать с GetProcAddress и освобождаете DLL с помощью FreeLibrary, когда она вам больше не нужна:


var
  Hbar: Thandle;
  Foo: procedure(X: Integer);
begin
  Hbar := LoadLibrary('BAR.DLL');
  if Hbar >= 32 then { успешно }
  begin
    Foo := GetProcAddress(HBar, 'FOO');
    ...
    Foo(1);
    ...
    FreeLibrary(HBar);
  end
  else
    MessageDlg('Ошибка: не могу найти BAR.DLL', mtError, [mbOk], 0)
end.






Copyright © 2004-2016 "Delphi Sources". Delphi World FAQ




Группа ВКонтакте   Ссылка на Twitter   Группа на Facebook