МІНІСТЕРСТВО ОСВІТИ І НАУКИ, МОЛОДІ ТА СПОРТУ УКРАЇНИ
НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ “ЛЬВІВСЬКА ПОЛІТЕХНІКА”
Кафедра ЕОМ
ЗВІТ
до лабораторної роботи №6
з курсу “ Системне програмування ”
СТВОРЕННЯ БІБЛІОТЕК ДИНАМІЧНОГО КОМПОНУВАННЯ ТА ЇХ ВИКОРИСТАННЯ В РЕЖИМІ НЕЯВНОГО ЗВ’ЯЗУВАННЯ
Львів 2012
Мета: Ознайомитись з технологією створення та використання бібліотек динамічного компонування з використанням неявного зв’язування.
ТЕОРЕТИЧНІ ВІДОМОСТІ
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 способи використання динамічних бібліотек. Вони називаються явним та неявним зв’язуванням. Явне та неявне зв’язування бібліотеки з програмою мають суттєві відмінності в процесі написання та компіляції програми.
Неявне зв’язування бібліотеки з програмою (Load-time dynamic linking) полягає в тому, що бібліотека (яка міститься у файлі з розширенням .dll) завантажується в пам’ять в момент завантаження програми. При відсутності бодай однієї з бібліотек при запуску програми відбудеться збій та припинення виконання програми.
Щоб реалізувати неявне зв’язування необхідно до проекту програми включити прототипи функцій, що містяться в бібліотеці та бібліотеку імпорту (має розширення .lib). На даному етапі наявність файлу з розширенням .dll не є необхідною. При компіляції лінкер створює виконавчий файл, який містить код, що забезпечує систему інформацією, яка необхідна для автоматичного завантаження бібліотеки з .dll файлу та інформацією, яка необхідна для зв’язування імен функцій у програмі з їх адресами у бібліотеці.
Неявне зв’язування дозволяє здійснювати виклик функцій з бібліотеки написанням коду програми в стилі притаманному мовам С\С++.
Варіант №25: Ввести два рядки тексту та ціле число N, порівняти між собою перші N символів в рядках, ігноруючи пробіли.
Коди програми
maindll.h
#ifndef _maindll_h_
#define _maindll_h_
#include <stdio.h>
#include <windows.h>
using namespace System;
extern "C" __declspec(dllexport) void CmpStrN(char* str1,char* str2,int N);
#endif
maindll.cpp
#include "maindll.h"
using namespace System;
extern "C" __declspec(dllexport) void CmpStrN(char* str1,char* str2,int N)
{
String^ str11=System::Runtime::InteropServices::Marshal::PtrToStringAnsi((IntPtr)str1);
String^ str12=System::Runtime::InteropServices::Marshal::PtrToStringAnsi((IntPtr)str2);
int index=0;
int err=0;
int i=0;
int j=0;
while(index<N){
if(str11[i] == ' ') i++;
if(str12[j] == ' ') j++;
if(str11[i] == str12[j]){
index++;
i++;
j++;
}
else{
index++;
i++;
j++;
err++;
}
}
if(err == 0) Console::WriteLine(N.ToString()+" - this string is similar!");
else Console::WriteLine(N.ToString()+" - this string is not similar!");
}
maintest.cpp
#include <conio.h>
#include "maindll.h"
#include <vcclr.h>
using namespace System;
void main()
{
String^ string1;
String^ string2;
String^ N;
Console::WriteLine("Enter first string:");
string1 = Console::ReadLine();
Console::WriteLine("Enter second string:");
string2 = Console::ReadLine();
Console::WriteLine("Enter 'N' for check:");
N = Console::ReadLine();
pin_ptr<const wchar_t> wch = PtrToStringChars(string1);
size_t string1size = wcslen(wch) + 1;
const size_t newsize = 100;
size_t convertedChars = 0;
char str1[newsize];
wcstombs_s(&convertedChars, str1, string1size, wch, _TRUNCATE);
strcat_s(str1, " (char *)");
pin_ptr<const wchar_t> wch1 = PtrToStringChars(string2);
size_t string2size = wcslen(wch1) + 1;
const size_t newsize1 = 100;
size_t convertedChars1 = 0;
char str2[newsize1];
wcstombs_s(&convertedChars1, str2, string2size, wch1, _TRUNCATE);
strcat_s(str2, " (char *)");
__int32 iN = System::Int32::Parse(N);
Console::WriteLine("Result:");
CmpStrN(str1,str2,iN);
_getch();
}
РЕЗУЛЬТАТ ВИКОНАННЯ ПРОГРАМИ
/
Рис. 1. Рядки одинакові
/
Рис. 2. Рядки не є однаковими
Висновок: На даній лабораторній роботі я ознайомився з технологією створення та використання бібліотек динамічного компонування з використанням неявного зв’язування.