Міністерство освіти і науки, молоді та спорту України
Національний університет “Львівська політехніка”
Кафедра ЕОМ
СТВОРЕННЯ БІБЛІОТЕК ДИНАМІЧНОГО КОМПОНУВАННЯ ТА ЇХ ВИКОРИСТАННЯ В РЕЖИМІ ЯВНОГО ЗВ’ЯЗУВАННЯ
Методичні вказівкидо лабораторної роботи № 7 з курсу “ Системне програмування ”
для студентів базового напряму 6.050102 - “Комп’ютерна інженерія”
Затвердженона засіданні кафедри”Електронні обчислювальні машини”Протокол № від року
Львів – 2011
Створення бібліотек динамічного компонування та їх використання в режимі явного зв’язування: Методичні вказівки до лабораторної роботи № 6 з курсу “ Системне програмування ” для студентів базового напряму 6.050102 - “Комп’ютерна інженерія” / Укладачі: Мархивка В.С., Олексів М.В., Акимишин О.І., Мороз І.В., – Львів: Національний університет “Львівська політехніка”, 2011, 8 с.
Укладачі Мархивка В.С., ст. викл.
Олексів М. В., асистент
Акимишин О.І., к.т.н., доцент
Мороз І.В., ст. викл.
Рецензенти
Відповідальний за випуск: Мельник А. О., професор, завідувач кафедри
СТВОРЕННЯ БІБЛІОТЕК ДИНАМІЧНОГО КОМПОНУВАННЯ ТА ЇХ ВИКОРИСТАННЯ В РЕЖИМІ ЯВНОГО ЗВ’ЯЗУВАННЯ
Мета: Ознайомитись з технологією створення та використання бібліотек динамічного компонування з використанням явного зв’язування.
ТЕОРЕТИЧНІ ВІДОМОСТІ
DLL (англ. Dynamic-link library — динамічно завантажувана бібліотека) — реалізовані компанією Microsoft загальні бібліотеки в ОС Windows. Як правило бібліотеки мають розширення файлу *.dll, *.ocx (для бібліотек, що містять елементи керування ActiveX) або *.drv (драйвери старих версій ОС). Структура DLL така сама, як і в PE-файлів (Portable Executable) для 32-, 64-розрядних Windows, та New-Executable (NE) для 16-бітових Windows.
DLL може містити 2 типи функцій: експортні та внутрішні. Експортні функції визначаються за допомогою ключового слова __declspec(dllexport) і можуть бути викликані з програм, що завантажили динамічну бібліотеку, яка містить ці функції. Внутрішні функції – це функції, які використовуються в середині DLL і не можуть бути викликані ззовні.
DLL є модулем (module). Тобто, вона складається з: сегментів коду, сегментів ресурсів та одного сегменту даних. Крім цього DLL може містити точку входу. Точка входу – це функція DllMain, яка викликається при завантаженні або вивантажені бібліотеки потоком або процесом. Ця функція має наступний прототип:
BOOL APIENTRY DllMain(
HANDLE hModule, // Хендл DLL модуля
DWORD ul_reason_for_call, // Причина виклику
LPVOID lpReserved ); // Зарезервовано
Якщо DllMain повертає FALSE, то бібліотека вважається такою, що не завантажилася. При неявному зв’язуванні це призведе до відмови запуску програми, а при явному – помилки завантаження лише цієї бібліотеки.
В процесі виконання вміст бібліотеки залишається незмінним (сегменти коду та сегменти ресурсів), що дозволяє завантажувати її в пам’ять в єдиному екземплярі і використовувати багатьма завданнями одночасно. Використання dll дозволяє економити пам’ять, забезпечити модульність програм, полегшити процес встановлення програм.
Можливі 2 способи використання динамічних бібліотек. Вони називаються явним та неявним зв’язуванням. Явне та неявне зв’язування бібліотеки з програмою мають суттєві відмінності в процесі написання та компіляції програми.
Явне зв’язування бібліотеки з програмою (Run-time dynamic linking) полягає в тому, що бібліотека (яка міститься у файлі з розширенням .dll) завантажується в пам’ять в момент виклику АРІ функції LoadLibrary або LoadLibraryEX програмою. При успішному виконанні функція повертає адресу точки входу. При відсутності бібліотеки, яку необхідно завантажити, або при помилках її завантаження функція поверне NULL, а сама програма продовжить виконання. Для виклику бібліотечної функції необхідно оголосити вказівник на функцію, та присвоїти йому адресу бібліотечної функції. Для цього необхідно використати АРІ функцію GetProcAddress, яка повертає адресу вказаної їй у параметрі бібліотечної функції. По завершенню роботи програми необхідно вивантажити бібліотек за допомогою функції FreeLibrary.
Для успішної компіляції необхідно мати лише dll файл бібліотеки. Запуск програми відбудеться навіть за відсутності бібліотечного файлу, оскільки його наявність при використанні явного зв’язування не перевіряється.
КОНТРОЛЬНІ ПИТАННЯ
1. Що таке DLL?
2. Що може міститися у DLL?
3. Що таке явне зв’язування?
4. Як реалізувати явне зв’язування?
5. Що необхідно мати для реалізації явного зв’язування?
ЛІТЕРАТУРА
1. Эпплман Д. Win32 API и Visual Basic. Для профессионалов (+CD). - СПб.: Питер, 2001. - 1120 с.: ил.
2. Юров В. Assembler: учебник. - СПб.: Питер, 2001. - 624 с.: ил.
3. Джонсон М. Харт Системное програмирование в среде Windows. 3-е издание.: Пер. с англ. – М.: Издательский дом «Вильямс», 2005. – 592 с.
ПОРЯДОК ВИКОНАННЯ
Написання програми складається з 2-ох етапів. На першому етапі створюється бібліотека. На другому етапі – створюється програма, яка викликатиме функції з створеної бібліотеки.
1. Для створення бібліотеки створюємо новий проект типу Win32 Project та в налаштуваннях вибираємо тип проекту DLL, так як показано на рис. 1:
Рис.1. Вибір типу проекту для створення DLL засобами MSVS
2. Створюємо заголовний файл бібліотеки (з розширенням .h) для забезпечення експортування інтерфейсів функцій. Приклад файлу наведено нижче.
Заголовний файл (DLLTEST.H)
#ifndef _DLLTEST_H_#define _DLLTEST_H_ #include <iostream>#include <stdio.h>#include <windows.h>
using namespace std;extern "C" __declspec(dllexport) void NumberList();extern "C" __declspec(dllexport) void LetterList();#endif
3. Створюємо .срр файл з вмістом коду бібліотеки. Приклад файлу наведено нижче.
Код бібліотеки (DLLTEST.CPP)
#include "dlltest.h"#define MAXMODULE 50char module[MAXMODULE];extern "C" __declspec(dllexport) void NumberList() { GetModuleFileName(NULL, (LPTSTR)module, MAXMODULE); cout << "This function was called from " << module << endl << endl; cout << "NumberList(): "; for(int i=0; i<10; i++) { cout << i << " "; } cout << endl << endl;}extern "C" __declspec(dllexport) void LetterList() { GetModuleFileName(NULL, (LPTSTR)module, MAXMODULE); cout << "This function was called from " << module << endl << endl; cout << "LetterList(): "; for(int i=0; i<26; i++) { cout << char(97 + i) << " "; } cout << endl << endl;}
Бібліотека містить 2 функції, які виводять текст на консоль. Рядок
extern "C" __declspec(dllexport)
означає, що функцію буде видно зовні DLL (тобто її можна викликати з іншої програми).
Після компіляції ми одержимо DLL – бібліотеку, яка складатиметься з 2-о файлів: dlltest.dll, dlltest.lib. Зауважимо, що дана бібліотека, хоч і не має явно оголошеної точки входу, проте функція DllMain все ж таки буде створена неявно, хоч нічого і не робитиме.
4. На другому етапі створюємо новий проект типу Win32 Project та в налаштуваннях вибираємо тип проекту Console Application.
5. Пишемо програму, яка здійснюватиме виклик функцій з бібліотеки як показано нижче. Компілюємо і запускаємо програму.
#include <windows.h>#include <iostream>#include <stdio.h>#include <conio.h>
using namespace std; #define MAXMODULE 50typedef void (WINAPI*cfunc)();cfunc NumberList;cfunc LetterList;void main() { HINSTANCE hLib=LoadLibrary("DLLTEST.DLL"); if(hLib==NULL) { cout << "Unable to load library!" << endl; getch(); return; } char mod[MAXMODULE]; NumberList=(cfunc)GetProcAddress((HMODULE)hLib, "NumberList"); LetterList=(cfunc)GetProcAddress((HMODULE)hLib, "LetterList"); if((NumberList==NULL) || (LetterList==NULL)) { cout << "Unable to load function(s)." << endl; FreeLibrary((HMODULE)hLib); return; } NumberList(); LetterList(); FreeLibrary((HMODULE)hLib); getch();}
6. Створюємо власну DLL бібліотеку для реалізації функцій згідно варіанту.
7. Створюємо програму, що використовує явне зв’язування DLL.
8. Готуємо та захищаємо звіт.
ВАРІАНТИ ЗАВДАНЬ
Дано текст. Підрахувати кількість слів в даному рядку.
Дано текст. Підрахувати кількість букв а в останньому слові даного рядка.
Дано текст. Знайти кількість слів, що починаються з заданої літери.
Дано текст. Знайти кількість слів, у яких перший і останній символи співпадають між собою.
Дано текст. Знайти довжину найкоротшого слова.
Скласти програму циклічної перестановки букв в словах тексту так, що i-а буква слова стає i+1-ою, а остання - першою.
У кожному слові тексту заміните "а" на букву "е", якщо "а" стоїть на парному місці, і замінити букву "б" на поєднання "ак", якщо "б" стоїть на непарному місці.
Написати програму, що здійснює в деякому тексті заміну заданих слів (врахувати, що слова можуть мати різну довжину!)
Даний текст, що містить від 2 до 30 слів, в кожному з яких від 2 до 10 латинських букв; між сусідніми словами - не менше одного пропуску. Надрукувати всі слова, відмінні від останнього слова, заздалегідь перетворивши кожне з них за наступним правилом: 1) перенести першу букву в кінець слова; 2) перенести останню букву в початок слова.
Відредагувати заданий текст, видаляючи з нього всі слова з непарними номерами
Відредагувати заданий текст, перевертаючи слова з парними номерами. Наприклад, HOW DO YOU DO -> OD OD
Даний текст. Надрукувати всі слова, відмінні від останнього слова
Даний текст. Залишити в словах тільки перші входження кожної букви;
Даний текст. Видалити середню букву в словах непарної довжини
Написати програму для підрахунку суми місць, на яких в словах тексту стоїть задана буква.
Скласти таблицю слів даного тексту, що починаються з букви "А", з вказівкою числа повторень кожного слова.
Скласти програму для викреслювання із слів тексту всіх букв, що стоять на непарних місцях.
Скласти програми для перекладу арабських чисел в римські і для зворотної операції. Наприклад, 255 = CCLV = сто + сто + п'ятдесят + п'ять Зауваження. Подібними алгоритмами перекладу чисел з однієї системи в іншу ми користуємося по декілька разів на дню, коли ведемо грошові розрахунки. Сума грошей - це арабське число, якому відповідає певний набір банкнот і монет (аналоги римських цифр).
Підрахувати, скільки букв треба виправити в слові Х, щоб вийшло слово Y (Х,Y - слова однакової довжини).
Скласти програму для підрахунку числа однакових букв в словах X і Y рівної довжини, що стоять на одних і тих же місцях.
Визначити, скільки заданих символів міститься в тексті, що вводиться з клавіатури.
З клавіатури вводиться текст. Підрахувати і вивести на друк кількість слів тексту, що починаються з голосної.
Для заданого тексту визначити довжину максимальної серії символів, відмінних від латинських букв, що міститься в ньому.
Записати програму, що з'ясовує, чи можна з букв слова X скласти слово Y.
Ввести два рядки тексту та ціле число N, порівняти між собою перші N символів в рядках, ігноруючи пробіли.
Ввести два рядки тексту, вилучити з довшого рядка всі входження коротшого рядка. Вивести новий рядок на екран.
Ввести два рядки тексту, провести “склейку” першого рядка до другого та вивести новий рядок на екран
Ввести рядок тексту, змінити регістр кожного символу, що є літерою і вивести новий рядок на екран.
Ввести рядок тексту та два окремі символи. Вилучити з вхідного рядка всі другі символи після того як зустрінеться перший символ. Вивести новий рядок на екран.
Ввести рядок тексту та один символ. Вилучити з вхідного рядка всі слова, що починаються на заданий символ. Вивести новий рядок на екран.
НАВЧАЛЬНЕ ВИДАННЯ
СТВОРЕННЯ БІБЛІОТЕК ДИНАМІЧНОГО КОМПОНУВАННЯ ТА ЇХ ВИКОРИСТАННЯ В РЕЖИМІ ЯВНОГО ЗВ’ЯЗУВАННЯ
МЕТОДИЧНІ ВКАЗІВКИ
до лабораторної роботи № 7 з дисципліни “ Системне програмування ”
для студентів базового напряму 6.050102 - “Комп’ютерна інженерія”
Укладачі Мархивка В.С., ст. викл.
Олексів М. В., асистент
Акимишин О.І., к.т.н., доцент
Мороз І.В., ст. викл.
Редактор
Комп’ютерне верстання
Здано у видавництво . Підписано до друку
Формат 70х100/16. Папір офсетний. Друк на різографі
Умовн. друк. арк. Обл..-вид. арк..
Тираж прим. Зам..
Видавництво Національного університету “Львівська політехніка”
Реєстраційне свідоцтво ДК №751 від 27.12.2001 р.
Поліграфічний центр Видавництва
Національного університету “Львівська політехніка”
Вул.. Ф. Колесси, 2. Львів, 79000