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

UptoLike

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

break;
case DLL_ THREAD_ATTACH: // Инициализация потока.
break;
case DLL_THREAD_DETACH: // Очистка структур потока.
break ;
case DLL_PROCESS_DETACH: // Очистка структур процесса.
break;
}
if(bAll WentWell)
return ТRUE ;
else
return FALSE;
}
Функция DllMain() вызывается в нескольких случаях. Причина ее вызова опреде-
ляется параметром dwReason, который может принимать одно из следующих значений.
При первой загрузке библиотеки DLL процессом вызывается функция DllMain() с пара-
метром dwReason, равным DLL_PROCESS_ATTACH. Каждый раз при создании процес-
сом нового потока (кроме первичного) DllMain() вызывается с параметром dwReason,
равным DLL_THREAD_ATTACH.
По окончании работы процесса с DLL функция DllMain() вызывается с параметром
dwReason, равным DLL_PROCESS_DETACH. При уничтожении потоков (кроме пер-
вичного) dwReason будет равен DLL_THREAD_DETACH.
Все операции по инициализации и очистке для процессов и потоков, в которых
нуждается DLL, необходимо выполнять на основании значения dwReason, как было по-
казано в предыдущем примере. Инициализация процессов обычно ограничивается выде-
лением ресурсов, совместно используемых потоками, в частности загрузкой разделяе-
мых файлов и инициализацией библиотек. Инициализация потоков применяется для
настройки режимов, свойственных только данному потоку, например для инициализа-
ции локальной памяти.
В состав DLL могут входить ресурсы, не принадлежащие вызывающему эту биб-
лиотеку приложению. Если функции DLL работают с ресурсами DLL, было бы, очевид-
но, полезно сохранить дескриптор hInst и использовать его при загрузке ресурсов из
DLL. Указатель lpReserved зарезервирован для внутреннего использования Windows.
Следовательно, приложение не должно претендовать на него. Можно лишь проверить
его значение. Если библиотека DLL была загружена динамически, оно будет равно
NULL. При статической загрузке этот указатель будет ненулевым. В случае успешного
завершения функция DllMain() должна возвращать TRUE. В случае возникновения
ошибки возвращается FALSE, и дальнейшие действия прекращаются.
1.3.3. Экспортирование функций из DLL
Чтобы приложение могло обращаться к функциям динамической библиотеки, каж-
дая из них должна занимать строку в таблице экспортируемых функций DLL. Есть два
способа занести функцию в эту таблицу на этапе компиляции. Можно экспортировать
функцию из DLL, поставив в начале ее описания модификатор _declspec (dllexport). В
языке C++ по умолчанию производится добавка к именам функций таким образом, что-
бы различать функции с разным количеством и типом параметров. Поэтому, чтобы
можно было вызывать функцию из другого модуля по ее обычному имени, ее следует
объявить как extern "С".
40
               break;
            case DLL_ THREAD_ATTACH: // Инициализация потока.
               break;
            case DLL_THREAD_DETACH: // Очистка структур потока.
               break ;
            case DLL_PROCESS_DETACH: // Очистка структур процесса.
               break;
      }
      if(bAll WentWell)
              return ТRUE ;
      else
              return FALSE;
}

     Функция DllMain() вызывается в нескольких случаях. Причина ее вызова опреде-
ляется параметром dwReason, который может принимать одно из следующих значений.
При первой загрузке библиотеки DLL процессом вызывается функция DllMain() с пара-
метром dwReason, равным DLL_PROCESS_ATTACH. Каждый раз при создании процес-
сом нового потока (кроме первичного) DllMain() вызывается с параметром dwReason,
равным DLL_THREAD_ATTACH.
     По окончании работы процесса с DLL функция DllMain() вызывается с параметром
dwReason, равным DLL_PROCESS_DETACH. При уничтожении потоков (кроме пер-
вичного) dwReason будет равен DLL_THREAD_DETACH.
     Все операции по инициализации и очистке для процессов и потоков, в которых
нуждается DLL, необходимо выполнять на основании значения dwReason, как было по-
казано в предыдущем примере. Инициализация процессов обычно ограничивается выде-
лением ресурсов, совместно используемых потоками, в частности загрузкой разделяе-
мых файлов и инициализацией библиотек. Инициализация потоков применяется для
настройки режимов, свойственных только данному потоку, например для инициализа-
ции локальной памяти.
     В состав DLL могут входить ресурсы, не принадлежащие вызывающему эту биб-
лиотеку приложению. Если функции DLL работают с ресурсами DLL, было бы, очевид-
но, полезно сохранить дескриптор hInst и использовать его при загрузке ресурсов из
DLL. Указатель lpReserved зарезервирован для внутреннего использования Windows.
Следовательно, приложение не должно претендовать на него. Можно лишь проверить
его значение. Если библиотека DLL была загружена динамически, оно будет равно
NULL. При статической загрузке этот указатель будет ненулевым. В случае успешного
завершения функция DllMain() должна возвращать TRUE. В случае возникновения
ошибки возвращается FALSE, и дальнейшие действия прекращаются.

     1.3.3. Экспортирование функций из DLL

     Чтобы приложение могло обращаться к функциям динамической библиотеки, каж-
дая из них должна занимать строку в таблице экспортируемых функций DLL. Есть два
способа занести функцию в эту таблицу на этапе компиляции. Можно экспортировать
функцию из DLL, поставив в начале ее описания модификатор _declspec (dllexport). В
языке C++ по умолчанию производится добавка к именам функций таким образом, что-
бы различать функции с разным количеством и типом параметров. Поэтому, чтобы
можно было вызывать функцию из другого модуля по ее обычному имени, ее следует
объявить как extern "С".


                                       40