Статична завантаження

Створимо спершу проект (File / New / DLL). Буде створений проект, що містить
наступне:

int WINAPI DllEntryPoint (HINSTANCE hinst, unsigned long reason, void *) {
return 1;
}

і довгий коментар застережливий вас про те, що для работо здібності
вашої DLL необхідно снеі забезпечити поствку деяких dll якщо ви використовуєте
екземпляри класу String.

Для експорту та імпорту з DLL необхідно використовувати моди фікатори __export
і __import відповідно. Але в C + + Builder можна використовувати нове ключове
слово __delspec () з параметрами dllexport і dllimport відповідно. Самі
розумієте, що для того щоб еспортіровать функції з бібліотеки еужен один
заголовний файл з описами _delspec (dllexport) для експортованих функцій,
для імпорту функцій у додаток вам необхідно буде поставити рівнів
заголовний файл але з _delspec (dllimport) описами, що досить незручно.
Ця проблема вирішується легко: додайте в заголовний файл бібліотеки наступне:

#if defined(BUILD_DLL)
# define DLL_EXP __declspec(dllexport)
#else
# if defined(BUILD_APP)
# define DLL_EXP __declspec(dllimport)
# else
# define DLL_EXP
# endif
#endif

у вихідному файлі DLL напишіть # define BUILD_DLL, а замість
__declspec (dllexport) пишіть DLL_EXP. При написанні програми додайте рядок
# Define BUILD_APP, і просто підключіть заголовний файл DLL.


Приклад DLL: файл P.cpp

//———————————————— —————————
#define BUILD_DLL
#include
#include "p.h"
#pragma hdrstop

//———————————————— —————————
/ / Important note about DLL memory management when your DLL uses the
// static version of the RunTime Library:
//
/ / If your DLL exports any functions that pass String objects (or structs /
/ / Classes containing nested Strings) as parameter or function results,
/ / You will need to add the library MEMMGR.LIB to both the DLL project and
/ / Any other projects that use the DLL. You will also need to use MEMMGR.LIB
/ / If any other projects which use the DLL will be perfomring new or delete
/ / Operations on any non-TObject-derived classes which are exported from the
/ / DLL. Adding MEMMGR.LIB to your project will change the DLL and its calling
/ / EXE "s to use the BORLNDMM.DLL as their memory manager. In these cases,
/ / The file BORLNDMM.DLL should be deployed along with your DLL.
/ / To avoid using BORLNDMM.DLL, pass string information using "char *" or
// ShortString parameters.
//
/ / If your DLL uses the dynamic version of the RTL, you do not need to
/ / Explicitly add MEMMGR.LIB as this will be done implicitly for you
//———————————————— ————————-
int WINAPI DllEntryPoint (HINSTANCE hinst, unsigned long reason, void *) {
return 1;
}

//———————————————— ————————-

void Message(char *s) {
i=10;
Application->MessageBox(s,"From DLL",IDOK);
}


Файл Ph

#if defined(BUILD_DLL)
# define DLL_EXP __declspec(dllexport)
#else
# if defined(BUILD_APP)
# define DLL_EXP __declspec(dllimport)
# else
# define DLL_EXP
# endif
#endif

DLL_EXP void Message(char *s);
DLL_EXP int i;


Скомпілюйте проект.


Якщо ви натиснете Run то після завершення побудови буде видане повідомлення
що дана програма не можнт бути виконана (природно). Тепер напишемо
викликає програму. Втомже каталозі создайде новий проект (File / New
Application) у форму помістіть одну кнопку і створи обробник події OnClick.
Ваш виконуваний файл повинен являти собою слдующее:

//———————————————— —————————
#include
#define BUILD_APP
#pragma hdrstop
#include "p.h"
#include "Unit1.h"
#include
//———————————————— —————————
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//———————————————— ————————-
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) {
}

//———————————————— ————————-
void __fastcall TForm1::Button1Click(TObject *Sender) {
char c[10];
Message("roma");
for( ; i>0;i–) {
sprintf(c,"Example %d",i );
Application-> MessageBox ("Example of using DLL variable", (char *) c, IDOK);
}
}

//———————————————— ————————-


Не забудьте про оголошення на початку файлу. Зайдіть в менеджер проектов.Там
відкрийте свій проект і додайте. lib файл з Попередні проект з DLL (правий
клік, пункт ADD). Запустіть проект.

Як бачите, для того, щоб вашу DLL можна було використовувати необхідно три
файлу: сама DLL, заголовний файл і бібліотечний файл. lib.

Динамічне завантаження


Динамічне завантаження горазда складніше. Однак для динамічного завантаження
потрібно тільки сама DLL (непотрібною ні. lib ні заголовний файл, хоча його
можна ісполбзовать для опису експортованих функцій для предполагемого
користувача).


Давайте розглянемо на прикладі, як виробляється динамічне завантаження.
Створіть новий Прокто DLL і внесіть до нього наступне:

extern "C" void __export  Message(char *s)  {
Application->MessageBox(s,"From DLL",IDOK);
}

Cкомпіліруйте проект, в результаті чого буде створена DLL.

Тепер створіть проект програми рівнів проекту для використання
статичної завантаження (форма з кнопкою і обробником події кнопки OnClick)
нижче наведений код програми: (Unit11.cpp)

//———————————————— —————————
#include
#pragma hdrstop
#include "Unit11.h"
#include
//———————————————— —————————
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//———————————————— —————————
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) {
}
//———————————————— —————————

void __fastcall TForm1::Button1Click(TObject *Sender) {
void (__stdcall *Message)(char *s);
HINSTANCE dllp = LoadLibrary("p.dll");
if (dllp) {
Message= (void(__stdcall *) (char*))
GetProcAddress(dllp, "_Message");
if (Message) Message("Hi From Dinamic DLL");
}
FreeLibrary(dllp);
}
//———————————————— —————————


запустіть це проект, при натисненні на кнопку повинно видаватся сообшеніе.
Тепер розберемося, як це працює.



Зверніть увагу на те, що прізагрузке можна вказати точне местоположніе
бібліотеки (необезательно в тому ж каталозі де і додаток).


слід стежити що б збігалися оголошення функції в *. dll і *. exe (зокрема
в цьому прикладі: __stdcall не збігаються, тому викидає External
exception)
наводжу робочий приклад:
void __fastcall
TForm1::Button1Click(TObject *Sender) {
void (*Message)(char
*s);
HINSTANCE dllp = LoadLibrary(“p.dll”);
if (dllp) {
Message=
(void(*) (char*))
GetProcAddress(dllp, “_Message”);
if (Message)
Message(“Hi From Dinamic DLL”);
}
FreeLibrary(dllp);
}
dll-ку
залишаємо колишню

Вміст параграфа "Сутність
динамічного зв'язування "

Статична і
динамічна компонування


Звичайна Windows-програма
являє собою виконуваний файл, який зазвичай створює одну або більше вікон,
а для отримання даних від користувача використовує цикл обробки
повідомлень.

·         Динамічно
бібліотеки (
DLL), Як правило, безпосередньо не
виконуються і зазвичай не отримують повідомлень. Вони представляють із себе окремі файли з функціями, Які викликаються
програмами та іншими DLL для виконання певних завдань. DLL активізується тільки тоді, коли інший модуль
викликає одну з функцій, що знаходяться в
бібліотеці
.


Розглянемо сутність динамічного і
статичного зв'язування (або компонування)

·         Статичний зв'язування
(Static linking) має місце в процесі зв'язування програми
, Коли для створення виконуваного
exe-файлу зв'язуються воєдино різні об'єктні
obj-модулі, lib-файли бібліотек
і, як правило, скомпільовані
res-файли ресурсів.

· Термін динамічне зв'язування (dynamic linking) відноситься до
процесам, які Windows використовує для того, щоб зв'язати виклик функції в
одному з модулів з реальною функцією з DLL
. На відміну від
статичного зв'язування динамічне зв'язування
має місце під час виконання програми
. У виконуваний файл
занесена тільки інформація про місцезнаходження
функцій DLL
(Цю інформацію додаток отримує з так званих
бібліотек імпорту).

У момент виконання програми
завантажується вся бібліотека цілком.
Завдяки цьому різні процеси можуть користуватися
спільно бібліотеками, що знаходяться в пам'яті.
Такий підхід дозволяє
скоротити обсяг пам'яті, необхідний для декількох додатків, що використовують
багато спільних бібліотек, а також контролювати розміри
exe-файлів.



Як правило, найбільший сенс DLL набувають у контексті великого
проекту (або пакета додатків)
. Зазвичай у таких програмах
використовуються деякі загальні підпрограми.

· Ці підпрограми можна помістити в звичайну об'єктну бібліотеку
(Файл із розширенням. Lib) і додати її до кожного програмного модулю при
компонуванні. Але такий підхід надмірний,
оскільки в цьому випадку в кожній програмі буде знаходитися однаковий код
підпрограм, виконують одні й ті ж завдання.

· Більше того, при зміні однієї
з підпрограм
в бібліотеці, необхідно
перекомпоновувати всі програми
, До складу яких входить ця
підпрограма.

· Однак якщо помістити всі ці общеіспользуемие підпрограми в динамічно підключається бібліотеку, то обидві
проблеми будуть вирішені
. Тільки в одному бібліотечному модулі потрібно
містити необхідні всім додаткам підпрограми, і можна змінити
бібліотечний модуль без перекомпонування додатків.

Три значення одного
слова "бібліотека"


У попередньому викладі
слово "бібліотека" зустрічається в різних контекстах. Крім динамічно
бібліотек, що підключаються воно згадується в поєднаннях "об'єктна бібліотек" та
"Бібліотека імпорту". Розберемося в цих поняттях.

Об'єктна
бібліотека – Це
файл з розширенням. lib, в якому міститься код,
додається до коду програми, що знаходиться у файлі c розширенням. exe, коли
йде компонування програми
.

· Наприклад, у Microsoft Visual C + +
звичайна об'єктна бібліотека, яка при компонуванні
приєднується до програми, називається libc.lib.

Бібліотека імпорту
являє собою особливу форму файлу об'єктної бібліотеки. Так само як об'єктні бібліотеки,
бібліотека імпорту має розширення. lib і використовується компонувальником для
розв'язання посилань на функції у вихідному тексті програми. Однак у бібліотеках імпорту програмного коду
немає
. Замість них у бібліотеках імпорту
знаходиться інформація, необхідна компонувальник для установки таблиці посилань
всередині exe-файлу, призначеної для динамічного
зв'язування.

Об'єктні бібліотеки та бібліотеки
імпорту (створювані одночасно з модулем DLL) використовуються тільки на етапі
розробки програми. Спільні
бібліотеки використовуються під час виконання програми
. Динамічно
бібліотека повинна знаходиться на диску,
коли виконується програма, що використовує цю
бібліотеку
.



Тому,


 
        extern “C” 
        {
 # Include "MyLib.h"
        }
 

Розглянемо тепер процес створення і використання DLL в найлегшому
варіанті
.

Наведемо вихідний код найпростішої бібліотеки динамічного
компонування
, Яка називається MyDLL і містить одну функцію
MyFunction, яка просто виводить повідомлення

MyDLL.h
 # Define EXPORT extern "C" __declspec (dllexport)
 EXPORT int CALLBACK MyFunction (char * str);
 
MyDLL.c
 # Include <windows.h>
 # Include "MyDLL.h"
 
 int WINAPI DllMain (HINSTANCE hInstance, DWORD fdReason, PVOID pvReserved)
        {
 return TRUE;
        }
 
 EXPORT int CALLBACK MyFunction (char * str)
        {
 MessageBox (NULL, str, "Function from DLL", MB_OK);
 return 1;
        }

 


Файл бібліотеки також
дещо відрізняється від звичайних файлів на мові C для Windows. У файлі бібліотеки замість функції
WinMain є функція DllMain. Ця функція використовується для виконання ініціалізації, Про що
буде розказано пізніше. Для того щоб бібліотека
залишилася після її завантаження в пам'яті
, І можна було викликати її
функції, необхідно, щоб повертається значенням функції DllMain було
TRUE.

Перейдемо до обговорення процесу використання створеної
DLL-бібліотеки
.

Наведемо тепер вихідний код простого застосування, яке використовує функцію
MyFunction
з
бібліотеки MyDLL.dll:

 
MyApp.c
# Include <windows.h>
 # Include "MyDLL.h"
 
 int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
        {
 int iCode = MyFunction ("Hello");
 return 0;
        }
 


Вміст параграфа "Способи
зв'язування додатки з DLL "

Розглянемо різні
способи зв'язування програми з
бібліотекою динамічної компоновки
.

Зв'язування
з DLL при завантаженні програми (неявне
підключення)

Якщо
при створенні програми, що викликає
функції DLL, використовується бібліотека
імпорту DLL
(Як зроблено в наведеному вище прикладі –
див. вихідний текст додатку MyApp), то цей спосіб
підключення DLL називається неявним
підключенням DLL
. Інформація з
бібліотеки імпорту необхідна
компонувальник для
установки таблиці посилань усередині exe-файлу,
призначеної для динамічного
зв'язування.

Windows
при завантаженні програми намагається знайти
всі файли DLL, неявно підключені до
додатком
,
і помістити їх в область оперативної
пам'яті, займану даним процесом. Пошук
файлів DLL операційною системою здійснюється
в такій послідовності
:

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Метки: , , , , ,
Рубрики: Програми та распространненой програм

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*