Реферат: Реализация отложенной загрузки библиотек на С
Класс модуля позволяет явно выгружать библиотеку (модуль) при помощи функции UnloadModule, однако пользоваться этой возможностью надо с большой осторожностью.
Реализация динамического поиска функций и глобальной таблицы импорта
Теперь рассмотрим детали реализации пунктов 6 и 7 (поиск адресов импортируемых функций и их вызов). Это наиболее нетривиальная и интересная в плане программирования часть библиотеки, поскольку функции могут иметь различное число параметров, а также различные типы возвращаемых значений. И напомню основное требование – естественный синтаксис вызова функций и минимизация обращений к GetProcAddress.
В данном случае для обеспечения требования минимизации вызовов GetProcAddress мы будем использовать технику создания прокси-функций. Фактически, при первом вызове импортируемой функции мы будем попадать в сформированную компилятором прокси-функцию, в которой будет производиться поиск адреса функции по ее имени в библиотеке и в зависимости от успешности поиска производится либо вызов функции, либо выполнение операции, заданной в стратегии реакции на ошибки поиска. Для того, чтобы в дальнейшем вызывалась непосредственно импортируемая функция, а не прокси, адрес, полученный в прокси, запоминается в глобальной для всех единиц трансляции таблице указателей на функции. Для создания таблицы используется техника, подобная применяемой в синглтоне Мейерса. В сильно упрощенном виде это выглядит так:
template <class Proxy> struct CGlobalProxyTable { static FARPROC &GetProxy() { static FARPROC proxy; return proxy; } }; |
В данном примере для каждого входного типа будет сгенерирован уникальный глобальный указатель типа FARPROC, фактически являющийся ячейкой глобальной в терминах единиц трансляций таблицы функций.
Для того, чтобы определить интерфейс ячейки таблицы функций, выясним, от чего зависит импортируемая функция. Очевидно, это имя функции, модуль, из которого надо ее импортировать, и прокси, используемый для определения адреса функции в загружаемой библиотеке. В связи с этим определим класс CDynFunction, инкапсулирующий ячейку для хранения адреса функции в глобальной таблице импортируемых функций:
template <class Module, class Name, class Proxy> class CDynFunction |
Учитывая все вышесказанное, реализация класса тривиальна и будет выглядеть так:
template <class Module, class Name, class Proxy> class CDynFunction { public: typedef CDynFunction<Module, Name, Proxy> type; typedef Proxy proxy_type; typedef Module module_type; typedef Name name_type; static typename proxy_type::fun_type &GetProxy() { static typename proxy_type::fun_type proxy = proxy_type::template Proxy<type>::ProxyFun; return proxy; К-во Просмотров: 428
Бесплатно скачать Реферат: Реализация отложенной загрузки библиотек на С
|