Лабораторная работа №38

Лабораторная работа №38
Разработка динамических библиотек
Цель: Изучить приёмы создания и использования библиотек динамической компоновки с неявным и явным подключением
Оснащение: IBM PC, Microsoft Visual Studio .NET

 

Вы не можете скачивать файлы с нашего сервера

Методические указания:

Для создания библиотек динамической компоновки необходимо выбрать в разделе Visual C++ win32 application или win32 console application. Затем в меню с радиокнопками выбрать DLL.

Вызов обычных функций из DLL

В библиотеке:
В разделе директив необходимо объявить макрос для замены текста 
_declspec(dllexport)
В случае несоответствия имён объявляемых функций в библиотеке и вызовом библиотечных функций из программ необходимо добавить extern “C” для того, чтобы компилятор не добавлял различные символы к имени функции.

В программе:
Неявное подключение библиотеки осуществляется стандартной директивой #include “MyDLL.dll”
Явное подключение осуществляется непосредственно в коде использованием функции LoadLibrary(), возвращающей объект структуры HMODULE. Структура HMODULE и функция LoadLibrary() содержатся в заголовочном файле <windows.h>.
Функция библиотеки вызывается с помощью указателя, следовательно, необходимо объявить указатель на функцию и получить её адрес функцией GetProcAddress.
Указатель на функцию объявляется так:
тип_возвращаемого_значения (* имя_указателя)(типы_аргументов);
Например:
void (* ptrFunc) (int, int)
Передача дескриптора функции из библиотеки указателю осуществляется так:
(FARPROC &) имя_указателя = GetProcAddress (дескриптор_библиотеки, имя_функции)
Например:
(FARPROC &)pFunction = GetProcAddress(hLib, "FuncName");
 FARPROC - это указатель на функцию, которая не принимает параметров и возвращает int. Именно такой указатель возвращает функция GetProcAddress.
Вызов функции по указателю осуществляется как обычно, например:
ptrFunc(0, 0);
После того, как вызов всех функций библиотеки закончен, библиотеку необходимо отключить функцией FreeLibrary(дескриптор_библиотеки).

Вызов методов классов из DLL

В библиотеке:
Объявление класса с предопределённым макросом EXPORT выглядит следующим образом:
class EXPORT MyClass
{
private:
  int a;

public:
  MyClass()
{ a=0; }

  int GetA()
{ return a; }

  void SetA(int _a)
{ a=_a; }
};
В программе:
Объекты класса из явно подключаемой библиотеки нельзя использовать, как обычно. Дело в том, что при создании объекта класса компилятор генерирует вызов его конструктора. Но линкер не может разрешить этот вызов, поскольку адрес конструктора будет известен только в процессе выполнения программы.
Вызвать конструктор можно вручную, получив его адрес и выделив память под объект. Например:

void (MyClass::*ptrConstr)(); //получаем указатель на конструктор
(FARPROC &)ptrConstr = GetProcAddress(hLib, "Constructor");

char *_obj = new char[sizeof(Class)]; //выделяем память в куче
Class *obj = (Class *)_obj; //создаём объект по выделенной памяти

obj->*ptrConstr(); //явно вызываем конструктор для этого объекта 

Остальные методы класса вызываются так же, как и конструктор, например:

void (MyClass::*pSetA)(int); //объявляем указатель на метод SetA
(FARPROC &)pSetA = GetProcAddress(hLib, "SetA"); //получаем адрес
(pc->*pSetA)(312); //вызываем метод по указателю

Исключением являются виртуальные методы, которые вызываются непосредственно. Для них не требуется явно получать адреса с помощью GetProcAddress.

После работы с объектом его необходимо уничтожить с помощью деструктора, например:

void (Class::*pDestr)(); //объявляем указатель на деструктор
(FARPROC &)pDestr = GetProcAddress(hLib, "Destructor"); 
(obj->*pDestr)(); // уничтожаем объект, созданный в куче
delete [] _obj; // освобождаем память
 
Задания:

1. Создать библиотеку для сортировки массива из 10 чисел. Библиотека содержит две функции для сортировок по возрастанию и по убыванию. Каждая функция принимает указатель на массив типа int в качестве аргумента.
2. Создать библиотеку, содержащую описание класса, содержащего информацию о почтовом адресе организации.



Обсудить на форуме

Комментарии к статье:

Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем
Информация
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.

Регистрация

Реклама

Последние комментарии