До сих пір ми використовували безліч функцій API для створення вікон і віконних процедур, малювання, роботи з клавіатурою і мишкою, введення-виведення. Всі ці функції працювали справно і ви не замислювалися над питанням: де розташовані ці функції і яким чином вони підключаються до вашій програмі. Все, що вам необхідно було зробити, це підключити відповідний заголовки (найчастіше це був
Почнемо з розгляду самого звичайного механізму використання функції, визначеної в вашій програмі. Наприклад, ви створюєте програму обчислення факторіала і визначаєте всередині програми функцію, яка безпосередньо цей факторіал обчислює:
// Функція обчислення факторіала
int NFactorial (int N)
else return NFactorial (N-1) * N;
Таким чином, ваша функція розташована прямо в тексті програми. Процес компіляції наведеної вище програми можна відобразити наступною схемою:
Файл factorial.cpp Файл factorial.obj Файл factorial.exe
Ріс.12.1 Компіляція програми зі статичним зв'язуванням першого виду
Статична зв'язування другого виду має на увазі використання в вашій програмі функцій, визначених в інших файлах (бібліотеках). Файли-бібліотеки як правило мають розширення * .lib і підключаються до вашого виконуваного файлу (* .exe) тільки на етапі компіляції і зв'язування (Рис.2). Таким чином, вони не компілюються заново, їх об'єктний код (аналог файлу * .obj) вже існує, і прикомпилируется до вашого файлу (* .obj) під час компіляції. Єдине, що необхідно зробити, це підключити потрібний файл -заголовок (* .h) в текст програми.
Файл factorial.cpp Файл factorial.obj Файл factorial.exe
Ріс.12.2 Компіляція програми зі статичним зв'язуванням другого виду
І, нарешті, ви маєте можливість використовувати спільні бібліотеки (* .dll). Функції, що знаходяться в них підключаються до вашого виконуваного файлу (* .exe) тільки в момент виклику, тобто в той момент, коли програма виконується і йде звернення до зазначеної функції. Таким чином, функції не компілюється разом з вашою програмою, не бере участі в процесі зв'язування і не міститься в вашому * .exe файлі. Такий підхід має незаперечні переваги:
1. Часто використовувані функції зберігаються в окремих файлах. Наприклад всі функції API реалізовані в DLL і поставляються разом з операційною системою. Таким чином, всі програми під Windows мають можливість використовувати одні і ті ж функції.
2. Немає необхідності поміщати всі функції програми в * .exe файл. Їх можна довантажувати в міру потреби.
3. Можливість використання нових версій функцій (dll-файлів) без перекомпіляції виконуваних модулів (exe-файлів).
Розглянемо процес створення і використання бібліотек DLL.
Процес створення динамічної бібліотеки проходить в два етапи. Перший з них полягає в створенні файлу-заголовка (* .h), який визначає основні властивості проекту.
За допомогою "візарду" середовища Microsoft Visual C ++ створіть новий проект, вибравши в якості типу проекту Dinamic Linked Library. після чого визначте "порожній проект" (empty project). Тепер вам доведеться самостійно створити файли проекту. Нехай ім'я вашого проекту буде funlib.
Створіть файл заголовка - funlib.h (за допомогою меню File \ New. Вибравши файл-заголовок). У цьому файлі наьеріте наступний текст:
#define EXPORT extern "C" __declspec (dllexport)
EXPORT BOOL CALLBACK return333 ();
EXPORT int CALLBACK MyInc (int i);
Тепер залишилося написати звичайний текст програми * .cpp, який мало чим відрізняється від звичайного:
int WINAPI DllMain (HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved)