Реферат: Реализация отложенной загрузки библиотек на С

Класс модуля позволяет явно выгружать библиотеку (модуль) при помощи функции 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
Бесплатно скачать Реферат: Реализация отложенной загрузки библиотек на С