Класс модуля позволяет явно выгружать библиотеку
(модуль) при помощи функции UnloadModule, однако пользоваться этой возможностью
надо с большой осторожностью.
Реализация динамического поиска функций и глобальной
таблицы импорта
Теперь рассмотрим детали реализации пунктов 6 и 7
(поиск адресов импортируемых функций и их вызов). Это наиболее нетривиальная и
интересная в плане программирования часть библиотеки, поскольку функции могут
иметь различное число параметров, а также различные типы возвращаемых значений.
И напомню основное требование – естественный синтаксис вызова функций и
минимизация обращений к GetProcAddress.
В данном случае для обеспечения требования минимизации
вызовов GetProcAddress мы будем использовать технику создания прокси-функций.
Фактически, при первом вызове импортируемой функции мы будем попадать в
сформированную компилятором прокси-функцию, в которой будет производиться поиск
адреса функции по ее имени в библиотеке и в зависимости от успешности поиска
производится либо вызов функции, либо выполнение операции, заданной в стратегии
реакции на ошибки поиска. Для того, чтобы в дальнейшем вызывалась
непосредственно импортируемая функция, а не прокси, адрес, полученный в прокси, запоминается в глобальной для всех единиц трансляции таблице указателей на
функции. Для создания таблицы используется техника, подобная применяемой в
синглтоне Мейерса. В сильно упрощенном виде это выглядит так: