2. Практическая часть. Создание Dynamic-Link Library в RAD Studio.
- 2.1. Создаём первую DLL своими руками.
Пришло время постепенно перейти от теории к практике. Открываем IDE (для написании данной статьи я использовал RAD Studio 2010). Переходим к File -> New -> Other -> Dynamic-Link Library. Перед нами возникает диалог:
Source Type - язык, на котором ведётся разработка. Use VCL - использование библиотеки визуальных компонентов. Multi Threaded - опция, указывающая на то, будет ли использоваться многопоточность в данной DLL (VCL уже подразумевает в себе многопоточность). VC++ Style DLL - опция, указывающая на то, будет ли DLL совместима с компиляторами Microsoft.
Если в совместимости нет нужды и опция не выбрана, то DLL будет иметь точку входу с таким прототипом:
Код C++ | 1
| int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved); |
| Для обеспечения совместимости точка входа изменяется на:
Код C++ | 1
| BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvReserved); |
| Оставим диалог без изменений и нажмём "ОК". Перед нами появится шаблон минимальной DLL. Сохраним его. Как вы помните, сама по себе DLL работать не может, ей нужен клиент. Поэтому, для удобства сразу создадим новый проект VCL Forms Application. Для этого переходим в Project Manager, вызываем контекстное меню у нашей Project Group и переходим к Add New Project -> VCL Forms Application. Для удобста я назвал проекты TestDLL и TestVCL соответственно (и сохранил их в одном каталоге - это избавит меня от копирования DLL или указания абсолютного пути):
Без изменений запускаем TestVCL, сохраняем и переключаемся к проекту TestDLL (дабл-клик на проекте вProject Manager).
Переходим к Run -> Parameters и в поле Host Application указываем путь к нашему проекту TestVCL.
К шаблону DLL добавляем функцию, которая будет вычислять сумму и выводить результат на экран:
Код C++ | 1
2
3
4
5
6
7
| #include "TestDLL.h" // создание этого заголовочного файла будет описано ниже
//---------------------------------------------------------------------------
void ShowSum(const int A, const int B)
{
ShowMessage(IntToStr(A) + " + " + IntToStr(B) + " = " + IntToStr(A + B));
}
//--------------------------------------------------------------------------- |
| В проекте TestDLL добавим также заголовочный файл (TestDLL.h) с таким содержанием:
Код C++ | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| #ifndef __TESTDLL_H
#define __TESTDLL_H
/*
символ TESTDLL_EXPORTS по умолчанию определен в Вашем проекте (см. Project Options -> С/С++ -> General->Preprocessor Definitions).
При этом все экспортируемые идентификаторы предваряются символом DLL_SPEC.
В случае определения TESTDLL_EXPORTS в проекте DLL_SPEC определяется как экспортируемый объект; в случае же отсутствия такого определения мы получим импортируемый объект.
Таким образом, один и тот же заголовочный файл может быть использован и в DLL-проекте, и в проекте, который будет использовать данную DLL! Без каких-либо изменений.
*/
#ifdef TESTDLL_EXPORTS
#define DLL_SPEC extern "C" __declspec(dllexport)
#else
#define DLL_SPEC extern "C" __declspec(dllimport)
#endif // TESTDLL_EXPORTS
/*
Каждый экспортируемый идентификатор предваряем __declspec(dllexport).
Эта директива позволяет линкеру определить, что данный идентификатор следует экспортировать из DLL. При этом создается специальный lib-файл, который содержит все экспортируемые идентификаторы из модуля. Также экспортируемые объекты заносятся в раздел экспорта DLL.
*/
DLL_SPEC void ShowSum(const int A, const int B);
#endif // __TESTDLL_H |
| Сохраняем. Запускаем. DLL мы подготовили. Теперь необходимо узнать, как же подключить DLL к проекту. Сделать это можно тремя способами. Рассмотрим их подробнее.
|