Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

7 Структурное программирование 2012

.pdf
Скачиваний:
12
Добавлен:
29.02.2016
Размер:
310.72 Кб
Скачать

31

Рисунок 7.4 – Окно подключения к программе lib-файла

Пример программа статического импорта созданных ресурсов DLL: //---------------------------------------------------------------------------

#include <iostream.h> // Подключение статических модулей

#include <conio.h> #pragma hdrstop #pragma argsused

extern "C" __declspec(dllimport) int Max(int X, int Y); // импорт функции Max extern "C" __declspec(dllimport) int Min(int X, int Y); // импорт функции Min int main(int argc, char* argv[]) // Главная функция -------------------------

{cout << "Maximum : " << Max(10,-5) << endl;

cout << "Minimum : " << Min(3,100); getch();

return 0; }//---------------------------------------------------------------------------

Cсуществует три способа динамического импорта функций из DLL:

1)по имени в программе;

2)по имени в DLL-библиотеке;

3)по индексу.

Два последних способа подразумевают использование DEF-файла.

На момент компиляции программы DLL-библиотека, которую она подключает, может еще и не существовать. Что означает независимую разработку приложений и DLL.

Подключить DLL-библиотеку в программе позволяет функция:

HINSTANCE LoadLibrary(LPCTSTR имя dll-файла);

При успешном завершении функция возвращает дескриптор загруженной DLLбиблиотеки, а иначе — код ошибки в диапазоне от 0 до 32.

Пример загрузки динамической библиотеки

HINSTANCE LibHandle;

if((LibHandle = LoadLibrary("MathLib.dll")) < (HINSTANCE)32)

{printf("Невозможно загрузить DLL\n");

return 1; }//--------------------

Если в памяти нет загруженной DLL-библиотеки с заданным именем, файл DLLбиблиотеки считывается с диска и загружается в оперативную память. Счетчик привязок динамической библиотеки увеличивается на 1 при каждом вызове LoadLibrary.

После завершения работы с библиотекой она освобождается функцией

BOOL FreeLibrary(дескриптор DLL). LoadLibrary и FreeLibrary можно вызывать для одного и того же модуля несколько раз.

32

После загрузки динамической библиотеки можно использовать функцию GetProcAddress для получения адресов экспортируемых функций. GetProcAddress возвращает указатель на точку входа в экспортируемую подпрограмму.

FARPROC GetProcAddress(HMODULE hModule, LPCSTR IpProcName);

где hModule — дескриптор загруженного DLL-модуля;

IpProcName — имя или целочисленный индекс подпрограммы, экспортируемой DLL. Если функция импортируется по имени, то в параметре IpProcName передается

указатель на строку, содержащую имя подпрограммы. Если экспорт по номеру, то в двух младших байтах параметра IpProcName передается ее индекс, а старшие два байта должны быть равны 0.

Если нет функции с указанным именем IpProcName, тогда GetProcAddress возвратит NULL. При попытке получить адрес подпрограммы не по имени, а по индексу, значение функции GetProcAddress будет не равно NULL, даже при отсутствии функции с указанным индексом. С помощью GetProcAddress не возможно получить только информацию о параметрах экспортируемой функции. При динамическом импорте очень удобными оказываются typedef объявление типа указателя на функцию. Пример указателя типа функций Min и Мах:

typedef int(*MinMax)(int, int) ;

Для хранения адреса функции DLL в программе объявляется переменная указанного типа. Например:

MinMax Min, Max;

Если теперь присвоить переменной Min результат вызова GetProcAddress, то ее можно будет использовать в дальнейшем для вызова функции динамической библиотеки.

Min = MinMax(GetProcAddress(LibHandle, "_Min"));

Знак подчеркивания перед именем Min необходим, так как компилятор C++Builder добавляет его ко всем именам, объявленным как extern "С".

Пример

 

 

 

#include <windows.h>

 

 

 

#include <iostream.h>

 

 

 

#include <conio.h>

 

 

 

#pragma hdrstop

 

 

 

#pragma argsused

 

 

 

typedef int(*MinMax)(int, int); // определение

типа указателя на функцию

MinMax Minn, Maxx;

// определение

указателей на функции

int main(int argc, char* argv[])

 

 

{ HINSTANCE LibHandle;

// Определение дескриптора DLL

if((LibHandle = LoadLibrary("ProjectDLL.dll"))

< (HINSTANCE)32) // Загрузка DLL

{ cout << "Невозможно загрузить DLL";

//

Сообщение об ошибке загрузки

getch();

 

//

приостановка закрытия окна

return -1;

 

//

Возврат кода ошибки

} //if

 

 

 

Minn=MinMax(GetProcAddress(LibHandle,"_Min"));

// импорт функции Min

Maxx=MinMax(GetProcAddress(LibHandle,"_Max"));

// импорт функции Max

cout << "Maximum : " << Maxx(10,-5) << endl;//

определение максимума двух чисел

cout << "Minimum : " << Minn(3,100);

//

определение минимума

FreeLibrary(LibHandle);

 

//

отключение DLL

getch();

 

//

приостановка закрытия окна

return 0;

 

//

код успешного завершения

}//---------------------------------------------------------------------------

 

 

 

Динамический импорт следующие достоинства:

1)более эффективное использование ресурсов оперативной памяти, так как DLL загружается и выгружается из памяти по мере надобности;

2)программе предоставляется полный контроль над подключением DLLбиблиотек, благодаря чему динамический импорт применим в тех случаях, когда подключаемые процедуры и функции могут отсутствовать в DLL-библиотеке и требуется особая обработка ошибок доступа к библиотеке и ее процедурам и функциям.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]