- •Лабораторная работа № 8 Создание и использование dll
- •Изучаемые вопросы
- •Теоретические сведения Функция DllMain. Последовательность вызовов в многопоточном приложении.
- •Экспорт/импорт функций
- •Экспорт/импорт ресурсов
- •Согласование интерфейсов
- •Загрузка явно подключаемой dll
- •Список динамических библиотек процесса
- •Динамическая загрузка и выгрузка dll
- •Вызов функции по номеру
Экспорт/импорт ресурсов
Динамическая загрузка применима и к ресурсам DLL. Для этого сначала необходимо вызвать функцию LoadLibrary:
hDllResource=LoadLibraryEx("DllResource.dll",0, LOAD_LIBRARY_AS_DATAFILE);
Устанавливаем флаг LOAD_LIBRARY_AS_DATAFILE,так как DLL содержит только ресурсы и никаких функций и а также его нужно указывать для загрузки EXE.
Для экспортирования ресурсов требуется переименовать resource.h, а затем добавить данный файл к коду нашего приложения, например, как приведено ниже.
#include "DllResource.h"
Согласование интерфейсов
При использовании собственных библиотек или библиотек независимых разработчиков придется обратить внимание на согласование вызова функции с ее прототипом.
По умолчанию в Visual C++ интерфейсы функций согласуются по правилам C++. Это значит, что параметры заносятся в стек справа налево, вызывающая программа отвечает за их удаление из стека при выходе из функции и расширении ее имени. Расширение имен (name mangling) позволяет редактору связей различать перегруженные функции, т.е. функции с одинаковыми именами, но разными списками аргументов. Однако в старой библиотеке С функции с расширенными именами отсутствуют.
Хотя все остальные правила вызова функции в С идентичны правилам вызова функции в C++, в библиотеках С имена функций не расширяются. К ним только добавляется впереди символ подчеркивания (_).
Если необходимо подключить библиотеку на С к приложению на C++, все функции из этой библиотеки придется объявить как внешние в формате С:
extern "С" int MyOldCFunction(int myParam);
Объявления функций библиотеки обычно помещаются в файле заголовка этой библиотеки, хотя заголовки большинства библиотек С не рассчитаны на применение в проектах на C++. В этом случае необходимо создать копию файла заголовка и включить в нее модификатор extern "C" к объявлению всех используемых функций библиотеки. Модификатор extern "C" можно применить и к целому блоку, к которому с помощью директивы #include подключен файл старого заголовка С. Таким образом, вместо модификации каждой функции в отдельности можно обойтись всего тремя строками:
extern "С"
{
#include "MyCLib.h"
}
В программах для старых версий Windows использовались также соглашения о вызове функций языка PASCAL для функций Windows API. В новых программах следует использовать модификатор winapi, преобразуемый в _stdcall. Хотя это и не стандартный интерфейс функций С или C++, но именно он используется для обращений к функциям Windows API. Однако обычно все это уже учтено в стандартных заголовках Windows.
Загрузка явно подключаемой dll
При запуске приложение пытается найти все файлы DLL, неявно подключенные к приложению, и поместить их в область оперативной памяти, занимаемую данным процессом. Поиск файлов DLL операционной системой осуществляется в следующей последовательности:
1)Каталог, в котором находится ЕХЕ-файл;
2)Текущий каталог процесса;
3)Системный каталог Windows.
Если библиотека DLL не обнаружена, система выводит диалоговое окно с сообщением о ее отсутствии и путях, по которым осуществлялся поиск. Объект-процесс не создается.
Если нужная библиотека найдена, она помещается в оперативную память процесса, где и остается до его окончания. Теперь приложение может обращаться к функциям, содержащимся в DLL.
Для неявного подключения библиотеки нужно в папку приложения поместить lib- файл и заголовочный файл. А так же, подключить к линковщику скопированный lib-файл.
#include "UsageDll.h"
#pragma comment(lib, "UsageDll.lib")
