Пример DLL
В следующем примере мы покажем, как присоединить к программе функцию из библиотеки. Причем библиотека эта будет не простая, а динамическая. Наиболее существенной особенностью динамических библиотек (DLL) является то, что содержащиеся в них процедуры, функции и ресурсы могут совместно использоваться несколькими приложениями. Это экономит, во-первых, место на диске (поскольку исключается дублирование кода), а во-вторых, оперативную память, когда в нее одновременно загружено несколько программ (по той же самой причине).
Последовательность действий в этом примере будет несколько сложнее, чем в предыдущих, так как мы здесь будем создавать сразу два программных модуля, связанных друг с другом: библиотеку и исполняемый модуль, который ее вызывает. Предлагаю вам проделать следующее:
Как я уже, кажется, говорил, желательно сохранять файлы каждого проекта в отдельном пустом каталоге.
- Поместите на форму две командных кнопки, назвав первую Call DLL, a вторую — Exit.
- Создайте (с помощью инспектора объектов) процедуру обработки события OnClick для первой кнопки и введите в нее строку: SayHelloO ;
- Вторая кнопка должна закрывать программу; проделайте для нее все то же самое, что и в примере предыдущего раздела.
- В верхней части файла, после всех директив #include, добавьте такую строчку: void export SayHello(void);
- С нашей главной программой пока все. Теперь откройте менеджер проектов (View | Project Manager). Наверху показан узел группы проектов с именем по умолчанию ProjectGroupl. Эта группа включает в себя пока всего один проект (HWDU.exe). Щелкните правой кнопкой мыши на узле группы и в контекстном меню выберите Add New Project...
- Появится знакомый вам диалог New Items; выберите в нем значок DLL (4-я версия) или DLL Wizard (версия 5). В группе проектов появится новый узел, и для него будет открыто новое окно в редакторе кода. Введите код функции SayHelloO и добавьте в верхней части директиву f include, чтобы файл принял следующий вид (комментарии я удалил):
- Сохраните проект DLL под именем SHello и постройте библиотеку, для чего вызовите для узла SHello. dll контекстное меню и выберите в нем Make. C++Builder компилирует исходный файл и создаст файл DLL; при этом он также генерирует (по умолчанию) библиотеку импорта SHello lib, которая требуется для компоновки исполняемого файла нашей программы.
- Теперь мы вернемся к проекту главной программы. (В верхней части менеджера проектов имеется выпадающий список; выберите в нем HWDlI.exe.) К нему следует присоединить библиотеку импорта уже построенной DLL, чтобы компоновщик мог разрешить ссылку на функцию SayHelLo () , вызываемую из главной программы (HWDlI.exe), но физически находящуюся в отдельно загружаемом файле (SHello.dll). Для этого вызовите контекстное меню ехе-узла и выберите в нем пункт Add. Появится стандартный диалог открытия файла.
- В выпадающем списке типов файлов выберите Library file (.lib). Вы должны увидеть библиотеку SHello.lib; выберите ее и закройте диалог. Библиотека будет присоединена к проекту HWDll.exe (рис. 2.10). Со храните группу проектов, выбрав в ее контекстном меню Save Project Group As...
- Теперь осталось только компилировать и запустить наше главное приложение. Для этого просто нажмите кнопку Run инструментальной панели. Когда появится окно программы, нажмите кнопку Call DLL. Будет вызвана функция из DLL SayHello(), которая отобразит панель сообщения (рис. 2.11).
Файл теперь должен иметь такой вид:
#include <vcl.h> ftpragma hdrstop
#include "HWDllU.h"
void export SayHello(void);
//--------------------------------
#pragma package(smart_init) #pragma resource "*.dfm" TFormI *Forml;
//---------------------------------------
_fastcall TFormI::TFormI(TComponent* Owner)
: TForm(Owner) {
}
//------------------------------------
void_fastcall TFormI::ButtonlClick(TObject *Sender) {
SayHello() ;
} //------------------------------------
void_fastcall TFormI::Button2Click(TObject *Sender)
forml->Close() ;
}
#include <vcl.h>
#include <windows.h>
#pragma hdrstop //----------------------------------
void _export SayHello(void)
{
MessageBox(NULL, "Hello World from DLL!",
"Simple Greeting", MB__OK | MB_ICONEXCLAMATION);
}
Lnt WINAPI DilEntryPoint(HINSTANCE hinst,
unsigned long reason, void*) {
return 1;
}
Рядом с пунктом контекстного меню Make (собрать) имеется пункт Build (построить). Если вы откроете Project в главном меню, то увидите там эквивалентные пункты Make SHello и Build SHello. Обе команды выполняют построение текущего проекта (его целевого файла). Разница в том, что Build компилирует и компонует заново все входящие в проект файлы, в то время как Make производит те или иные действия лишь при необходимости, например, при модификации кода в одном исходном файле будет компилироваться только этот файл, после чего будет выполнена компоновка программы.
Рис. 2.10 Менеджер проектов, показывающий Структуру группы
Рис. 2.11 Вызов функции DLL
То, что мы сейчас проделали, называется статической загрузкой динамической библиотеки. Суть ее в том, что DLL (если она еще не загружена) автоматически загружается в память при запуске главной программы. Библиотека импорта необходима именно для статической загрузки, при которой все ссылки на DLL разрешаются еще на этапе компоновки.
Возможна и динамическая загрузка DLL, которая, однако, выполняется вручную, т. е. специально написанным для этого программным кодом; достоинство ее в том, что она может производиться лишь при необходимости. При этом разрешение ссылок на DLL происходит уже во время выполнения, — другими словами, программе приходится “на ходу” как-то искать нужную функцию в DLL (например, по имени).
Вот, собственно, и все о DLL. Хотя динамические библиотеки (да и всякие другие) выходят за рамки тематики этой книги и в дальнейшем изложении нам встречаться больше не будут, нам показалось полезным дать читателю некоторое представление о том, как создание и использование этих библиотек выглядит в C++Builder.
Заключение
В этой главе мы показали типичные действия, выполняемые при разработке приложений в интегрированной среде C++Builder. Конечно, представленные здесь программы совершенно ничтожны, однако они работают, а заставить что-то заработать в Windows — это не шутка. В следующих главах мы переходим уже собственно к вопросам программирования и изучению различных конструкций языка C/C++.