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

UptoLike

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

Структура простейшей экспортируемой функции в этом случае может выглядеть
следующим образом.
extern "C" __declspec (dllexport) int MyFunction(…)
{
return 0;
}
Кроме этого для экспорта функций, можно использовать файлы определения мо-
дуля *.def. Синтаксис файлов с расширением .def в достаточно прямолинеен, главным
образом потому, что сложные параметры, использовавшиеся в ранних версиях Windows,
в Win32 более не применяются. Как станет ясно из следующего простого примера, .def-
файл содержит имя и описание библиотеки, а также список экспортируемых функций:
MyDLL.def
LIBRARY "MyDLL"
DESCRIPTION 'MyDLL - пример DLL-библиотеки'
EXPORTS MyFunction @1
В строке экспорта функции можно указать ее порядковый номер, поставив перед
ним символ @. Этот номер будет затем использоваться при обращении к функции
GetProcAddress(), которая будет описана далее. На самом деле компилятор присваивает
порядковые номера всем экспортируемым объектам. Однако способ, которым он это де-
лает, отчасти непредсказуем, если не присвоить эти номера явно. В строке экспорта
можно использовать параметр NONAME. Он запрещает компилятору включать имя
функции в таблицу экспортирования DLL:
MyFunction @1 NONAME
Иногда это позволяет сэкономить много места в файле DLL. Приложения, исполь-
зующие библиотеку импортирования для неявного подключения DLL, не "заметят" раз-
ницы, поскольку при неявном подключении порядковые номера используются автома-
тически. Приложениям, загружающим библиотеки DLL динамически, потребуется
передавать в GetProcAddress() порядковый номер, а не имя функции.
В отличие от статических библиотек, которые, по существу, становятся частью ко-
да приложения, динамические библиотеки в 16-разрядных версиях Windows работали с
памятью несколько иначе. Под управлением Win16API память DLL размещалась вне ад-
ресного пространства задачи. Размещение динамических библиотек в глобальной памя-
ти обеспечивало возможность совместного использования их различными задачами.
В Win32API библиотека DLL располагается в области памяти загружающего ее
процесса. Каждому процессу предоставляется отдельная копия "глобальной" памяти
DLL, которая реинициализируется каждый раз, когда ее загружает новый процесс. Это
означает, что динамическая библиотека не может использоваться совместно, в общей
памяти, как это было в Win16.
И все же, выполнив ряд замысловатых манипуляций над сегментом данных DLL,
можно создать общую область памяти для всех процессов, использующих данную биб-
лиотеку. Допустим, имеется массив целых чисел, который должен использоваться всеми
процессами, загружающими данную DLL. Это можно запрограммировать следующим
образом:
41
     Структура простейшей экспортируемой функции в этом случае может выглядеть
следующим образом.

extern "C" __declspec (dllexport) int MyFunction(…)
{
       …
       return 0;
}

     Кроме этого для экспорта функций, можно использовать файлы определения мо-
дуля *.def. Синтаксис файлов с расширением .def в достаточно прямолинеен, главным
образом потому, что сложные параметры, использовавшиеся в ранних версиях Windows,
в Win32 более не применяются. Как станет ясно из следующего простого примера, .def-
файл содержит имя и описание библиотеки, а также список экспортируемых функций:

MyDLL.def

        LIBRARY       "MyDLL"
        DESCRIPTION 'MyDLL - пример DLL-библиотеки'
        EXPORTS MyFunction @1

      В строке экспорта функции можно указать ее порядковый номер, поставив перед
ним символ @. Этот номер будет затем использоваться при обращении к функции
GetProcAddress(), которая будет описана далее. На самом деле компилятор присваивает
порядковые номера всем экспортируемым объектам. Однако способ, которым он это де-
лает, отчасти непредсказуем, если не присвоить эти номера явно. В строке экспорта
можно использовать параметр NONAME. Он запрещает компилятору включать имя
функции в таблицу экспортирования DLL:

      MyFunction     @1 NONAME

     Иногда это позволяет сэкономить много места в файле DLL. Приложения, исполь-
зующие библиотеку импортирования для неявного подключения DLL, не "заметят" раз-
ницы, поскольку при неявном подключении порядковые номера используются автома-
тически. Приложениям, загружающим библиотеки DLL динамически, потребуется
передавать в GetProcAddress() порядковый номер, а не имя функции.
     В отличие от статических библиотек, которые, по существу, становятся частью ко-
да приложения, динамические библиотеки в 16-разрядных версиях Windows работали с
памятью несколько иначе. Под управлением Win16API память DLL размещалась вне ад-
ресного пространства задачи. Размещение динамических библиотек в глобальной памя-
ти обеспечивало возможность совместного использования их различными задачами.
     В Win32API библиотека DLL располагается в области памяти загружающего ее
процесса. Каждому процессу предоставляется отдельная копия "глобальной" памяти
DLL, которая реинициализируется каждый раз, когда ее загружает новый процесс. Это
означает, что динамическая библиотека не может использоваться совместно, в общей
памяти, как это было в Win16.
     И все же, выполнив ряд замысловатых манипуляций над сегментом данных DLL,
можно создать общую область памяти для всех процессов, использующих данную биб-
лиотеку. Допустим, имеется массив целых чисел, который должен использоваться всеми
процессами, загружающими данную DLL. Это можно запрограммировать следующим
образом:


                                           41