Реализация отложенной загрузки библиотек на С++
Категория реферата: Рефераты по информатике, программированию
Теги реферата: виды шпаргалок, реферат мировой
Добавил(а) на сайт: Puzanov.
1 2 3 4 5 6 7 8 9 10 11 | Следующая страница реферата
Реализация отложенной загрузки библиотек на С++
Андрей Солодовников
Вы все еще грузите библиотеки вручную?
Тогда мы идем к вам!
Краткая предыстория
По специфике моей работы мне довольно часто приходится вручную загружать библиотеки и динамически, при помощи GetProcAddress, импортировать множество функций. Это происходит отчасти потому, что требуется обеспечить совместимость с различными версиями Windows, в которых целевые функции могут отсутствовать, отчасти потому, что так бывает удобнее (например, при реализации механизма плагинов). Конечно, всегда хочется это автоматизировать, особенно если функций и библиотек много. С одной стороны, в линейке Visual C++ для этого есть поддержка компиляторалинкера в виде механизма Delay Load, с другой стороны, бытует мнение, что использовать этот метод является дурным тоном, и, наверное, это так. Одна из основных причин, которую хочется отметить особенно – этот механизм является microsoft-specific, то есть никаких гарантий, что написанный Вами код будет работать и на других компиляторах или платформах, нет. Более того, несколько раз «попав» на странное поведение этого механизма (например, см. Q218613), мы от его использования в своих проектах отказались.
Следующим шагом был поиск готового подходящего функционала. Как ни странно, такого не находилось, несмотря на то, что проблема действительно имеет место быть. Многие решения были слишком просты и неоптимальны (например, это решение). Они не позволяли определять импорт сразу нескольких функций из одной библиотеки, либо для этого нужно было написать приличное количество кода. Они вызывали GetProcAddress и LoadLibrary в любое время, когда им вздумается, а на самом деле – чуть ли не при каждом обращении к импортируемой функции. Другие (например, такое решение) было достаточно сложно и неудобно использовать.
ПРИМЕЧАНИЕ На самом деле, указанные варианты вполне могут быть использованы в небольших проектах, когда не требуется импортировать большое количество функций. Однако их использование в любом случае требует достаточно много усидчивости и терпения, по крайней мере, меня это не устраивало. |
И общий недостаток всех этих решений – они были и есть неоптимальны. Особенно это касается количества кода, генерируемого компилятором (да и программистом) на одну импортируемую функцию и быстродействия полученного кода.
Все это, вкупе с потраченным временем, сподвигло меня к необходимости написания очередного велосипеда в виде библиотеки эмуляции Delay Load, а также и этой статьи.
Требования к библиотеке, реализующей механизм Delay load
В данном параграфе мы рассмотрим более подробно, каким базовым требованиям должен удовлетворять механизм динамической загрузки библиотек.
Исходя из описанного выше, можно сформулировать следующие требования к механизму поддержки динамической загрузки библиотек:
Как можно большая независимость от компилятора С++ (в пределах ANSI C++). Минимальные требования к компилятору – библиотека должна быть полностью функциональна на всех Visual C++ компиляторах, начиная с Visual C++ 6.0;
Минимальное количество кода, генерируемого компилятором, которое приходится на одну импортируемую функцию;
Удобство определения в проекте импортируемых библиотекфункций;
Возможность задания своих стратегий (реакций) на ошибки загрузки библиотекинахождения функции;
Минимизация вызовов LoadLibrary. Для одной библиотеки (модуля) вызов LoadLibrary должен производится один раз вне зависимости от количества импортируемых из нее функций. Данный механизм должен работать не только в пределах одной единицы трансляции, но и проекта в целом. Таким образом, должна создаваться единая для приложения таблица используемых модулей;
Минимизация вызовов GetProcAddress. GetProcAddress должен вызываться только при первом обращении к импортируемой функции, в дальнейшем все вызовы импортируемой функции должны производиться напрямую;
Библиотека должна обеспечивать привычный синтаксис вызова – не должно быть никаких внешних отличий от обычного вызова функции из С/С++;
Должны поддерживаться UNICODE версии импортируемых функций, причем, желательно, на основе заголовков от соответствующих статически линкуемых библиотек, в которых определены соответствующие макросы.
Из описанных выше требований наиболее важными и интересными представляются пункты 3,5,6 и 7. Особенности их реализации будут рассмотрены более подробно далее вместе с программной реализацией библиотеки. Для тех, кому детали реализации не интересны, а интересны методы использования библиотеки, предлагается приступать сразу к разделу Использование библиотеки.
Предлагаемая реализация библиотеки
Класс, инкапсулирующий работу с модулями
Для начала рассмотрим требование (5) к реализации загрузки библиотекмодулей. Очевидно, что обеспечить выполнение данного требования с условием уникальности экземпляра библиотеки в пределах всех единиц трансляции проекта можно использованием паттерна Singlton для загружаемого модуля. При этом для каждого различного загружаемого модуля должен создаваться собственный экземпляр синглтона, который и будет обеспечивать «одноразовую» загрузку в конструкторе и в дальнейшем выгрузку библиотеки в деструкторе. Эта задача решается определением шаблонного класса CModule. Имя библиотеки должно служить значением, относительно которого производится инстанцирование объекта, инкапсулирующего загрузку библиотеки. Поскольку в качестве паттерна Singlton используется синглтон Мейерса, то в качестве бонуса мы получаем отложенную загрузку библиотек (поскольку создание экземпляра синглтона производится при первом обращении к порождающей функции).
СОВЕТ Напомню, что простейшая реализация синглтона Мейерса выглядит следующим образом: |
||||
template <class T> Рекомендуем скачать другие рефераты по теме: реферат великая, рецензия на дипломную работу образец. 1 2 3 4 5 6 7 8 9 10 11 | Следующая страница реферата Поделитесь этой записью или добавьте в закладкиКатегории: |