Операционные системы. Учебное пособие. Марапулец Ю.В. - 41 стр.

UptoLike

Составители: 

ственно в исходном коде. Компоновщик вставляет ссылки на эти процедуры при их об-
наружении в связанной с приложением библиотеке импорта либо через раздел IMPORTS
файла определений модуля для данного приложения. Во время выполнения приложения,
загрузчик Windows помещает DLL-библиотеки в память и разрежает эти ссылки. При
запуске приложение пытается найти все файлы DLL, неявно подключенные к приложе-
нию, и поместить их в область оперативной памяти, занимаемую данным процессом.
Поиск файлов DLL операционной системой осуществляется в следующей последова-
тельности:
каталог, в котором находится ЕХЕ-файл;
текущий каталог процесса;
системный каталог Windows.
Если библиотека DLL не обнаружена, приложение выводит диалоговое окно с сообще-
нием о ее отсутствии и путях, по которым осуществлялся поиск. Затем процесс отклю-
чается. Если нужная библиотека найдена, она помещается в оперативную память про-
цесса, где и остается до его окончания. Теперь приложение может обращаться к
функциям, содержащимся в DLL. Для импорта функций библиотеки необходимо ис-
пользовать строку __declspec (dllimport).
Эта форма динамического связывания наиболее проста, однако при некоторых ус-
ловиях она может создавать проблемы. Например, если приложение ссылается на про-
цедуру из DLL таким способом, в случае его реализации DLL-библиотека должна суще-
ствовать даже тогда, когда приложение никогда не обращается к процедуре. Кроме того,
на этапе компиляции приложение должно знать имена всех процедур, которые будут
связываться во время загрузки. Для этого используется специальный файл с расширени-
ем .lib. Однако .lib-файл, используемый при неявном связывании DLL, — это не обыч-
ная статическая библиотека. Такие .lib-файлы называются библиотеками импортирова-
ния (import libraries). В них содержится не сам код библиотеки, а только ссылки на все
функции, экспортируемые из файла DLL, в котором все и хранится. В результате биб-
лиотеки импортирования, как правило, имеют меньший размер, чем DLL-файлы. Созда-
ются такие файлы обычно средой разработки одновременно с .dll. Имя .lib-файла опре-
деляется среди прочих параметров редактора связей в командной строке или на вкладке
"Link" диалогового окна "Project Settings" среды Developer Studio. В библиотеках языка
С имена функций не расширяются, поэтому если необходимо подключить библиотеку
на С к приложению на C++, все функции из этой библиотеки придется объявить как
внешние в формате С:
extern "С" __declspec (dllimport) int MyOldCFunction(int myParam) ;
Рассмотрим простой пример подключения библиотеки с поздним неявным связы-
ванием. В качестве Dll используем приведенную выше. Исходный код приложения сле-
дующий:
#include <windows.h>
extern "C" __declspec (dllimport) int MyFunction (char *str);
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR
lpCmdLine, int nCmdShow)
{
int iCode=MyFunction ("Hello!");
return 0;
}
43
ственно в исходном коде. Компоновщик вставляет ссылки на эти процедуры при их об-
наружении в связанной с приложением библиотеке импорта либо через раздел IMPORTS
файла определений модуля для данного приложения. Во время выполнения приложения,
загрузчик Windows помещает DLL-библиотеки в память и разрежает эти ссылки. При
запуске приложение пытается найти все файлы DLL, неявно подключенные к приложе-
нию, и поместить их в область оперативной памяти, занимаемую данным процессом.
Поиск файлов DLL операционной системой осуществляется в следующей последова-
тельности:
• каталог, в котором находится ЕХЕ-файл;
• текущий каталог процесса;
• системный каталог Windows.
Если библиотека DLL не обнаружена, приложение выводит диалоговое окно с сообще-
нием о ее отсутствии и путях, по которым осуществлялся поиск. Затем процесс отклю-
чается. Если нужная библиотека найдена, она помещается в оперативную память про-
цесса, где и остается до его окончания. Теперь приложение может обращаться к
функциям, содержащимся в DLL. Для импорта функций библиотеки необходимо ис-
пользовать строку __declspec (dllimport).
      Эта форма динамического связывания наиболее проста, однако при некоторых ус-
ловиях она может создавать проблемы. Например, если приложение ссылается на про-
цедуру из DLL таким способом, в случае его реализации DLL-библиотека должна суще-
ствовать даже тогда, когда приложение никогда не обращается к процедуре. Кроме того,
на этапе компиляции приложение должно знать имена всех процедур, которые будут
связываться во время загрузки. Для этого используется специальный файл с расширени-
ем .lib. Однако .lib-файл, используемый при неявном связывании DLL, — это не обыч-
ная статическая библиотека. Такие .lib-файлы называются библиотеками импортирова-
ния (import libraries). В них содержится не сам код библиотеки, а только ссылки на все
функции, экспортируемые из файла DLL, в котором все и хранится. В результате биб-
лиотеки импортирования, как правило, имеют меньший размер, чем DLL-файлы. Созда-
ются такие файлы обычно средой разработки одновременно с .dll. Имя .lib-файла опре-
деляется среди прочих параметров редактора связей в командной строке или на вкладке
"Link" диалогового окна "Project Settings" среды Developer Studio. В библиотеках языка
С имена функций не расширяются, поэтому если необходимо подключить библиотеку
на С к приложению на C++, все функции из этой библиотеки придется объявить как
внешние в формате С:

extern "С" __declspec (dllimport) int MyOldCFunction(int myParam) ;

     Рассмотрим простой пример подключения библиотеки с поздним неявным связы-
ванием. В качестве Dll используем приведенную выше. Исходный код приложения сле-
дующий:

#include 

extern "C" __declspec (dllimport) int MyFunction (char *str);

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR
lpCmdLine, int nCmdShow)
{
       int iCode=MyFunction ("Hello!");
       return 0;
}

                                             43