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

static BOOL InitFunction()

{

#ifdef DL_MT

static volatile LONG lMutex = FALSE;

#endif // DL_MT

const module_type &theModule = module_type::GetModule();

if (theModule.IsLoaded())

return DL_GetProcAddressImpl(

#ifdef DL_MT

lMutex,

(const FARPROC)proxy_type::template Proxy<type>::ProxyFun,

#endif //DL_MT

(volatile FARPROC &)GetProxy(),

theModule.GetModuleHandle(),

name_type::GetStr()

);

return FALSE;

}

};

Функция DL_GetProcAddressImpl представляет собой обертку GetProcAddress, и вынесена в отдельный функциональный элемент для уменьшения размера кода при поддержке многопоточности. Статический метод GetProxy() вернет глобальный в смысле единиц трансляции адрес в таблице функций, причем изначально по этому адресу находится адрес прокси функции. Таким образом, вызывая функцию по указателю, полученному при помощи GetProxy(), мы первоначально вызываем прокси, а в дальнейшем будем вызывать импортируемую функцию напрямую.

Реализация прокси функций

До этого момента все было достаточно очевидно и довольно просто. Однако при попытке реализации класса, определяющего функционал прокси-функции, мы сталкиваемся с проблемами. Чтобы понять, в чем они заключаются, рассмотрим параметры, необходимые для генерации прокси функции. Это:

тип возвращаемого значения импортируемой функции;

список типов параметров импортируемой функции;

стратегия реакции на ошибку поиска функции в модуле;

тип ячейки глобальной таблицы указателей на импортируемые функции (CDynFunction), который будет использован при создании прокси.

Как известно, С++ не поддерживает шаблоны с переменным количеством параметров. В связи с этим придется использовать генерацию экземпляров шаблона при помощи макросов а-ля boost::preprocessor. Объяснять подробно здесь, как это работает, я не буду – это тема для отдельной статьи. Кроме того, все это удовольствие осложняется тем, что Visual C 6.0 не может возвращать из void функции тип void. Для обхода этой проблемы приходится создавать отдельные классы для «нормальных» типов и для void, а затем использовать специализацию шаблона по возвращаемому значению с последующим наследованием.

Рассмотрим реализацию, предлагаемую в библиотеке:

#define FUN_PROXY(n) DL_CAT(CFunProxy,n)

#define FUN_PROXY_IMPL(n) DL_CAT(FUN_PROXY(n),Impl)

К-во Просмотров: 430
Бесплатно скачать Реферат: Реализация отложенной загрузки библиотек на С