Часть полного текста документа:Реализация отложенной загрузки библиотек на С++ Андрей Солодовников Вы все еще грузите библиотеки вручную? Тогда мы идем к вам! Краткая предыстория По специфике моей работы мне довольно часто приходится вручную загружать библиотеки и динамически, при помощи GetProcAddress, импортировать множество функций. Это происходит отчасти потому, что требуется обеспечить совместимость с различными версиями Windows, в которых целевые функции могут отсутствовать, отчасти потому, что так бывает удобнее (например, при реализации механизма плагинов). Конечно, всегда хочется это автоматизировать, особенно если функций и библиотек много. С одной стороны, в линейке Visual C++ для этого есть поддержка компилятора\линкера в виде механизма Delay Load, с другой стороны, бытует мнение, что использовать этот метод является дурным тоном, и, наверное, это так. Одна из основных причин, которую хочется отметить особенно - этот механизм является microsoft-specific, то есть никаких гарантий, что написанный Вами код будет работать и на других компиляторах или платформах, нет. Более того, несколько раз "попав" на странное поведение этого механизма (например, см. Q218613), мы от его использования в своих проектах отказались. Следующим шагом был поиск готового подходящего функционала. Как ни странно, такого не находилось, несмотря на то, что проблема действительно имеет место быть. Многие решения были слишком просты и неоптимальны (например, это решение). Они не позволяли определять импорт сразу нескольких функций из одной библиотеки, либо для этого нужно было написать приличное количество кода. Они вызывали GetProcAddress и LoadLibrary в любое время, когда им вздумается, а на самом деле - чуть ли не при каждом обращении к импортируемой функции. Другие (например, такое решение) было достаточно сложно и неудобно использовать. ПРИМЕЧАНИЕ На самом деле, указанные варианты вполне могут быть использованы в небольших проектах, когда не требуется импортировать большое количество функций. Однако их использование в любом случае требует достаточно много усидчивости и терпения, по крайней мере, меня это не устраивало. И общий недостаток всех этих решений - они были и есть неоптимальны. Особенно это касается количества кода, генерируемого компилятором (да и программистом) на одну импортируемую функцию и быстродействия полученного кода. Все это, вкупе с потраченным временем, сподвигло меня к необходимости написания очередного велосипеда в виде библиотеки эмуляции Delay Load, а также и этой статьи. Требования к библиотеке, реализующей механизм Delay load В данном параграфе мы рассмотрим более подробно, каким базовым требованиям должен удовлетворять механизм динамической загрузки библиотек. Исходя из описанного выше, можно сформулировать следующие требования к механизму поддержки динамической загрузки библиотек: Как можно большая независимость от компилятора С++ (в пределах ANSI C++). Минимальные требования к компилятору - библиотека должна быть полностью функциональна на всех Visual C++ компиляторах, начиная с Visual C++ 6.0; Минимальное количество кода, генерируемого компилятором, которое приходится на одну импортируемую функцию; Удобство определения в проекте импортируемых библиотек\функций; Возможность задания своих стратегий (реакций) на ошибки загрузки библиотеки\нахождения функции; Минимизация вызовов LoadLibrary. ............ |