Динамическое использование DLL
|
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.
|
|