СТВОРЕННЯ DLL ТА ЇХ ВИКОРИСТАННЯ ПРИ НЕЯВНОМУ ЗВ’ЯЗУВАННІ НА МОВІ С

Інформація про навчальний заклад

ВУЗ:
Національний університет Львівська політехніка
Інститут:
Не вказано
Факультет:
Не вказано
Кафедра:
Кафедра ЕОМ

Інформація про роботу

Рік:
2015
Тип роботи:
Лабораторна робота
Предмет:
Системне програмування та операційні системи

Частина тексту файла (без зображень, графіків і формул):

Міністерство освіти, науки, молоді та спорту України Національний університет “Львівська політехніка” Кафедра ЕОМ Звіт до лабораторної роботи №6 з дисципліни: «Системне програмування» на тему: “СТВОРЕННЯ DLL ТА ЇХ ВИКОРИСТАННЯ ПРИ НЕЯВНОМУ ЗВ’ЯЗУВАННІ НА МОВІ С” Підготував: *********** Прийняв: *********** Львів 2015 Мета: Ознайомитись з технологією та оволодіти навиками створення та використання бібліотек динамічного компонування з використанням неявного зв’язування. ТЕОРЕТИЧНІ ВІДОМОСТІ Завершальним етапом створення програмного продукту є процес збирання (компонування) завантажувального модуля (.exe – файлу). Компонуванням (linking) називають процес створення фізичного або логічного виконуваного файла (модуля) із набору об’єктних файлів бібліотек для подальшого виконання або під час виконання і вирішення проблеми неоднозначності імен, що виникає при цьому. У разі створення фізичного виконуваного файла для подальшого виконання компонування називають статичним, коли у такому файлі міститься все потрібне для виконання програми. У випадку створення логічного виконуваного файла під час виконання програми компонування називають динамічним, у цьому випадку образ виконуваного модуля збирають “на ходу”. Статичне компонування виконуваних файлів має низку недоліків:  якщо кілька застосувань використовують спільний код (наприклад, код бібліотеки мови С), кожний виконуваний файл міститиме окрему копію цього коду в результаті такі файли займатимуть значне місце на диску і у пам’яті;  під час кожного оновлення застосування, його потрібно наново перекомпонувати і перевстановити;  неможливо реалізувати динамічне завантаження програмного коду під час виконання. Для вирішення цих і подібних проблем було запропоновано концепцію динамічного компонування із використанням динамічних або розділюваних бібліотек. Динамічна бібліотека (англ. Dynamic-Load Library — динамічно завантажувана бібліотека) - набір функцій, скомпонованих разом у вигляді бінарного файлу, який може бути динамічно завантажений в адресний простір процесу, що використовує ці функції. Динамічне завантаження- завантаження під час виконання процесу. Динамічне компонування - компонування образу виконуваного файла під час виконання процесу із використанням динамічних бібліотек. До переваги використання динамічних бібліотек, слід віднести:  оскільки бібліотечні функції містяться в окремому файлі, розмір виконуваного файла стає меншим;  якщо динамічну бібліотеку використовують кілька процесів, у пам’ять завантажують лише одну її копію, після чого сторінки коду бібліотеки відображаються в адресний простір кожного з цих процесів;  оновлення застосування може бути зведене до встановлення нової версії динамічної бібліотеки без необхідності перекомпонування тих його частин, які не змінилися;  динамічні бібліотеки дають змогу застосуванню реалізовувати динамічне завантаження модулів на вимогу;  динамічні бібліотеки дають можливість спільно використовувати ресурси застосування;  оскільки динамічні бібліотеки є двійковими файлами, можна організувати спільну роботу бібліотек, розроблених із використанням різних мов програмування. Використання динамічних бібліотек не позбавлене недоліків:  динамічне зв’язування сповільнює завантаження застосування. Що більше таких бібліотек потрібно процесу, то більше файлів треба йому відобразити у свій адресний простір під час завантаження, а відображення кожного файла забирає час;  при відсутності спільного використання динамічної бібліотеки іншими застосування зовнішня пам’ять може використовуватися не ефективно. На відміну від статичного зв’язування, коли зі загальної бібліотеки вибираються тільки ті функції, що використовуються застосування, при використанні динамічного зв’язування до застосування необхідно додавати повну версію бібліотеки, навіть, якщо використовуються тільки декілька функцій. При значних обсягах бібліотеки втрати пам’яті відчутні;  найбільшою проблемою у використанні динамічного компонування є проблема зворотної сумісності динамічних бібліотек. Ця проблема виникає в ситуації, коли застосування встановлює нову версію DLL поверх попередньої. Якщо нова версія не має зворотної сумісності із попередніми, застосування, розраховані на використання попередніх версій бібліотеки, можуть припинити роботу;  ускладнюється процес інсталювання програмного продукту, в процесі якого необхідно досліджувати які з DLL вже інстальовано в ОС і які їх версії. Інстальована нова версія DLL з некоректною зворотною сумісністю, може негативно вплинути на виконання інших програм, що її використовують і навіть не підозрюють про підміну бібліотеки. Використання DLL у Windows Загальні бібліотеки функцій в ОС Windows реалізовані компанією Microsoft за DLL технологією. Як правило, ці бібліотеки мають розширення файлу *.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 способи використання динамічних бібліотек. Вони називаються “явним” та “неявним” зв’язуванням. “Явне” та “неявне” зв’язування бібліотеки з програмою мають суттєві відмінності в процесі написання та компіляції програми. Неявне зв’язування бібліотеки з програмою (Load-time dynamic linking) полягає в тому, що бібліотека (яка міститься у файлі з розширенням .dll) завантажується в пам’ять в момент завантаження програми. При відсутності бодай однієї з бібліотек при запуску програми відбудеться збій та припинення виконання програми. Щоб реалізувати неявне зв’язування необхідно до проекту програми включити прототипи функцій, що містяться в бібліотеці та бібліотеку імпорту (має розширення .lib). На даному етапі наявність файлу з розширенням .dll не є необхідною. При компоновці створюється виконавчий файл, який містить код, що забезпечує систему інформацією, яка необхідна для автоматичного завантаження бібліотеки з .dll файлу та інформацією, яка необхідна для зв’язування імен функцій у програмі з їх адресами у бібліотеці. Неявне зв’язування дозволяє здійснювати виклик функцій з бібліотеки написанням коду програми в стилі притаманному мовам С\С++. Завдання Ввести два рядки тексту, вилучити з довшого рядка всі входження коротшого рядка. Вивести новий рядок на екран. На першому етапі створюємо бібліотеку (файли dll26.dll і dll26.lib) засобами MSVS. Для цього створюємо проект типу DLL, в якому два файли: dll26.h i dll26.cpp: //dll26.h #ifndef _DLL26_H_ #define _DLL26_H_ #include <iostream> using namespace std; extern "C" __declspec (dllexport) void Vidnim(char *s1, char *s2); #endif //dll26.cpp #include "dll26.h" extern "C" __declspec (dllexport) void Vidnim(char *s1, char *s2){ char* beg = s1; char* end; char* temp = s2; int pos = 0; while (*beg && *beg != *s2) { ++beg; ++pos; } if (!(*beg)) return; end = beg; while(*end && *end == *temp) { ++end; ++temp; } if (end-beg == strlen(s2)) { strncpy(s1+pos, end, strlen(end)); s1[strlen(s1)-strlen(s2)] = '\0'; Vidnim(s1+pos, s2); } else Vidnim(beg+1, s2); } Після компіляції отримаємо бібліотеку (файли dll26.dll і dll26.lib, яка містить одну функцію: void Vidnim(char *s1, char *s2), яка вилучає з одного рядка інший (від s1 віднімає s2). На другому етапі будуємо проект консольного типу, пишемо програму, яка дозволяє ввести два рядки символів і порівнявши їхні довжини, вилучає з довшого рядка всі входження коротшого, використовуючи для цього функцію Vidnim() з побудованої бібліотеки. Код програми: //laba6.cpp // Laba6.cpp: #include "dll26.h" #include <iostream> using namespace std; int main() { char *str1=new char[80]; char *str2=new char[80]; cout << "Enter string str1: "; gets(str1); cout << "Enter string str2: "; gets(str2); if (strlen(str1)<strlen(str2)){ Vidnim(str2,str1); cout << "String-result: str2-str1= "<<str2<<endl; } else { Vidnim(str1,str2); cout << "String-result: str1-str2= "<<str1<<endl; } delete [] str1; delete [] str2; system("pause"); return 0; } Також в цьому проекті використовуємо заголовочний файл: //dll26.h #ifndef _DLL26_H_ #define _DLL26_H_ #include <iostream> using namespace std; extern "C" __declspec (dllexport) void Vidnim(char *s1, char *s2); #endif Детальний опис роботи коду Для роботи з рядками використовуємо вказівники типу char (масиви символів new char [80]).Вводимо два рядки (str1, str2) символів з допомогою функції gets() (цю функцію використовуємо, щоб можна було оперувати з пробілами при вводі – дозволяє зчитати весь рядок цілком). Порівнюємо довжини введених рядків і викликаємо побудовану нами в бібліотеці функцію Vidnim(char *s1, char *s2), в яку передаємо на місці першого параметра довший рядок, і відповідно коротший на місці другого параметра. Функція працює рекурсивно за принципом – знайшовши вкладення другого рядка в перший, вилучаємо з першого рядка вкладення другого (шляхом переписування першого рядка без вилученої частини) і з залишком першого рядка на місці першого параметру (другим параметром постійно виступає коротший рядок) знову викликається функція Vidnim(). Повторення відбуваються, доки не закінчиться рядок, або залишок першого рядка не стане коротшим за другий. Після завершення роботи бібліотечної функції повертаємось в основну програму і виводимо на екран відповідний (довший) рядок вже без вилучених вставок коротшого (якщо такі були). Результат виконання програми: / Висновок: на цій лабораторній роботі я навчилась створювати бібліотеки та використовувати виклики функцій з цих бібліотек при неявному звязуванні.
Антиботан аватар за замовчуванням

05.03.2017 21:03-

Коментарі

Ви не можете залишити коментар. Для цього, будь ласка, увійдіть або зареєструйтесь.

Ділись своїми роботами та отримуй миттєві бонуси!

Маєш корисні навчальні матеріали, які припадають пилом на твоєму комп'ютері? Розрахункові, лабораторні, практичні чи контрольні роботи — завантажуй їх прямо зараз і одразу отримуй бали на свій рахунок! Заархівуй всі файли в один .zip (до 100 МБ) або завантажуй кожен файл окремо. Внесок у спільноту – це легкий спосіб допомогти іншим та отримати додаткові можливості на сайті. Твої старі роботи можуть приносити тобі нові нагороди!
Нічого не вибрано
0%

Оголошення від адміністратора

Антиботан аватар за замовчуванням

Подякувати Студентському архіву довільною сумою

Admin

26.02.2023 12:38

Дякуємо, що користуєтесь нашим архівом!