Динамикалық кітапханалар

МАЗМҰНЫ

 

 

 

 

КІРІСПЕ

 

Бағдарламалау технологиясының дамуына байланысты көптеген адамдар өздерінің бағдарламаларының мүмкіндіктерін жоғарлату қателіктерімен соқтығысып жатады. Осы менің курстық жұмысым осы сұраққа арналған, яғни Borland Delphi тілінде DLL – ді бағдарламауға. Сонымен қоса, DLL кітапханаларын пайдалану туралы сұрақтарды қарастырғанда, біз басқа DLL – дан импорттауды да қарастырып кетеміз.

Динамикалық кітапхана жайында курстық жұмыс барысында толық түсіндіреміз. Динамикалық кітапханаға кіріспе бере кететін болсақ, алдымен біз динамикалық кітахананың қандай аймақтарда қолданылатыны айта кетейік.

Енді DLL кітапханалар не үшін керек және қай жерде қолданылады деген сұраққа жауап берейік, олардың қолданылатын жерлерінің кейбіреулеріне тоқталып кетейік:

- Бағдарламалаушы үшін қажетті қосымша функцияларды құрайтын жекелеген кітапханалар. Мысалы, жолдармен жұмыс жасайтын функциялар, немесе суретті өндейтін қиын кітапханалар.

- Ресурстарды сақтайтын жер. DLL-де тек қана программаларды және функцияларды сақтауға болмайды, сонымен қатар барлық мүмкін болатын ресурстарды- иконкілерді, суреттерді, жолдық массивтерді, менюді және т.б. сақтауға болады.

- Қолдау кітапханалары. Бұл кітапханаларға мысал ретінде бәрімізге белгілі: DirectX, ICQAPI (API для ICQ), OpenGL және т.б. пакеттерді жатқызуға болады.

- Бағдарлама бөліктері. Мысалы, DLL-де бағдарлама терезесін (формаларды) және т.с.с. сақтауға болады.

- Плагиндер (Plugins) – бағдарламаушының ойы үшін нағыз қарайтын жер осы плагиндерде. Плагиндер бағдарламаға оның мүмкіндіктерін кеңейтетін қосымша.

- Бөліп тұратын ресурс. DLL (Dynamic Link Library) бірден көптеген бағдарламаларда және процесстерде (sharing – бөліп тұратын ресурс) қолданыла алады.

Динамикалық кітапханалардың жалпылама қолданылатын жерлерін жалпылама айта кеттік, енді динамикалық кітапхана туралы курстық жұмыс барысында айта кетерміз. Сонымен қоса, бұл жұмыста Borland Delphi программалау ортасында DLL құру жайында және құрылған динамикалық кітапханаларды құрған мысалдарын көрсетіп кетеміз.

 

 

1. ДИНАМИКАЛЫҚ  КІТАПХАНА ТУРАЛЫ ЖАЛПЫ ТҮСІНІК

 

1.1 Модульдер

 

 

Модуль – бұл өзіне интерфейстік бөлімнің әртүрлі компоненттерін және инициалданатын бөлімнің кейбір орындалатын операторларын қосатын автоматты компиляцияланатын бағдарламаның бірлігі. Интерфейстік бөлімде объектілердің пайда болуы оларды басқа модульдер және негізгі бағдарламалар үшін қол жетімді қылады. Процедура мен функцияның денесі модульдің орындалатын бөлігінде орналасады. Ол пайдаланушыдан жасырын тұруы мүмкін. 

Delphi де модульдің рөлі  тек қана жеке компиляция механизмімен  шектелмейді. Delphi әрбір қосылған  бағдарламаны өзіне сай модульмен  байланыстырады және терезенің  барлық қасиеттерін жеке бағдарламалық  бірлікте локальдайды. Бағдарламаның барлық негізгі жұмысы модульде жататын кодтармен басқарылады.

 

Модульдер құрылымы:

 

Модуль келесі құрылымдардан тұрады:

 

Unit <имя>;

 

interface

 

<интерфейстік бөлім> implementation

 

<орындалатын бөлім> initialization <иницияланатын бөлім> finalization <аяқталатын бөлім>

 

end.

 

Мұнда unit – резервтелген сөз (бірлік); модульдің тақырыпшасын бастайды; <аты> - модуль аты (дұрыс идентификатор); interface – резервтелген сөз (интерфейс); модульдің интерфейстік бөлімін бастайды; implementation – резервтелген сөз (орындалуы); орындалатын бөлімді бастайды; initialization – резервтелген сөз (инициация); модульдің инициалданатын бөлімін бастайды; finalization – резервтелген сөз (аяқтау); модульдің аяқталатын бөлімін бастайды; end – резервтелген сөз; модульдің аяқталуының белгісі.

Демек, модуль тақырыпшадан және төрт құрылымдық бөлімнен құрылады. Бұл құрылымдық бөлімдердің кейбіреуі бос болуы мүмкін.

 

1.2 DELPHI - дегі модульдер типтері

 

 

Форма Delphi-дегі кең тараған модуль типі болып саналады. Мұндай модульдің интерфейстік бөлімі әдетте жаңа классты хабарлауды және Delphi дің терезені конструктрлеу барысында автоматты түрде жаңаруын құрайды. Форма модулінің интерфейстік бөлімінде сәйкес терезелік класс үшін объектіні хабарлауда болады.

Формалардан басқа репозиторияда көрсетілген тереземен байланыспаған модульдерде болады. Жоғарыда көрсетілген модульден басқа оларға деректер модулі де жатады. Ондай модулге динамикалық кітапхана, пакеттер және құйындар модулі жатады.

Деректер модулі олармен байланысқан терезелерден тұрады, бірақта, бұл терезелер ешқашан экранға шықпайды.

Динамикалық кітапхана модулдері Windows - те кең қолданылатын бір бірімен динамикалық байланысқан DLL (Dynamic-Link Libraries) кітапханаларды құруға арналған. DLL-дер туралы алда тағыда қарастырып кетеміз.

Пакеттер – бұл DLL компилацияланған түрінің  бір түрі. DLL-ден айыырмашылығы пакеттер бағдарламаға типтер мен деректерді сақтап және бере алады. Олар компоненттерді сақтау үшін арнайы өнделген. Мысалы, VCL60 .bpl пакеті Delphi дің негізгі компоненттерінен тұрады.

Құйындар модулі құйындар командасы деп аталатындарды іске асыруға арналған . құйындар механизмдері 32-разрядты Windows та қолданылады және Delphi 1- ді қолдамайды.

 

 

1.3 Динамикалық кітапханалар

 

 

Динамикалық кітапханалар (DLL, Dynamic Link Library) Windows операциялық жүйелерін және қосымша бағдарламаларды функционарлау кезінде маңызды рөл атқарады. Олар өзімен бірге компилияциядан өткен орындалған кодтары бар файлдарды көрсетеді. Ол файлдар қосымшалармен және басқа да DLL-дермен қолданылатын файлдар. Операциялық жүйенің көптеген функцияларын іске асыру динамикалық кітапханаларға енгізілген. Олар нағыз қажет болған кезде қолданылады және де олар адресстік кеңістікті экономдауды қамтамассыз етеді. DLL-ге қандай да бір процесс жолыққан кезде ол жадыға жүктеледі. 

Динамикалық кітапханалардың орындалған файлдардан айырмашылығы олардың өздігінен жүктеле алмауы. Динамикалық кітапхана өз жұмысын бастау үшін оны орындалып жатқан бағдарлама немесе жұмыс жасап жатқан DLL шақыруы керек.

Әдетте динамикалық кітапханаларда функциялар тобы енгізіледі. Ол функциялар тапсырмаларды шешу үшін қолданылады. Сонымен қоса, оларда жолдардан бастап формаларға дейінгі әртүрлі ресурстарды сақтауға және қолдануға болады.

Динамикалық кітапхана бірнеше қосымшалармен қолданыла алады, сонымен қоса олардың бәрі бір ғана бағдарламалау тілінің көмегімен жазылуын талап етпейді.

Динамикалық кітапхананың әртүрлілігі болып Delphi пакеті саналады. Ол пакет қосымшаларды және өндеу ортасы үшін компоненттер кодын сақтауға арналған.

Динамикалық кітапханаларды қолдану келесі мүмкіншіліктерге алып келеді:

  1. Қосымшаның және олардың ресурстарымен орындалатын файлдардың өлшемін азайтады;
  2. DLL функциялары бірнеше процесстерді бір уақытта қолдана алады;
  3. Динамикалық кітапханаларды басқару операциялық жүйеге жүктеледі;
  4. DLL - ге өзгеріс енгізу барлық проектіні компиляциядан өткізуді талап етпейді;
  5. Бір DLL ді әртүрлі тілде жазылған бағдарламалар қолдана алады.

Delphi ортасында динамикалық  кітапханаларды өндеу кезінде өзіне қосымша проектісін және динамикалық кітапханалар проектісін қосатын проекттілер тобын пайдаланған ыңғайлы.

DLL (ағылшынша Dynamic-link library –  динамикалық компоновкалардың кітапханасы) – Microsoft Windows және IBM OS/2 операциялық  жүйелердің түсінігі; қосымшаларға  әртүрлі бағдарламаларды қолдануды орындайды. DLL - ге ActiveX және драйверлерді басқару элементтері де жатады. UNIX әлемінде аналогты функцияларды shared objects («айыратын объектілер») орындайды.

DLL файлдарының форматтары  орындалатын файлдардың форматында  орындалады. Оларға код, кестелер  және ресурстарды да жатқызуға  болады.

DLL - ге кіріспе жүргізу мақсаттары

Алдынғы кездерде DLL-ге кіріспе жүргізу жадыны және дисктік жүйелерді эффективті түрде ұйымдастыруды жүзеге асырады. Ол барлық қосымшалар үшін кітапханалық модульдің  тек қана бір данасын қолданады. Бұл жадының қатқыл шектеулерімен Microsoft Windows - тың бұрынғы нұсқаларына маңызды болып келеді.

Бертін келе, модульділік арқасында өндеу эффективтілігін және жүйелік құралдарды қолдануды жақсартуды қолға ала бастады. DLL-бағдарламаларды бір нұсқасынан басқа нұсқасына ауыстыру жүйені тәуелсіз жалғауды, яғни қосымшаға тиіспей, іске асыруы керек болды. Сонымен қоса, DLL кітапханалары  әртүрлі типтегі қосымшаларды қолдана алды. Мысалы, Microsoft Office, Microsoft Visual Studio және т.с.с.

Ары қарай модульділік ойы COM концепциясына өсті.

DLL-ді енгізудің толық артықшылықтарын алу DLL Hell («ад DLL») атты туындының себебінен мүмкін болмады. DLL Hell көптеген қосымшалар бір уақытта бір біріне байланыссыз DLL - кітапханаларының нұсқаларын талап еткен жағдайда туындайды. Жүйе нақты бір өлшемге өскен кезде, DLL саны мыңдап көбее бастайды, олардың бәрі толық сенімділікпен сәйкестікке ие болмады және DLL Hell типтес араздастықтар жиі шығатын болды. Бұл араздастықтар жүйенің жалпы сенімділігін тез азайтатын болды. Microsoft Windows соңғы нұсқалары DLL - дің әртүрлі нұсқаларын параллельді қолдануға мүмкіндік беретін болды. Бұл жағдай модульділіктің бастапқы принциптерінің мүмкіншіліктерін болдырмауға әкеп соқтырды.

 

 

1.4 DLL-дан экспорттау

 

 

Динамикалық кітапханалардан процедуралар мен функцияларды экспорттауын құру үшін exports кілттік сөзі қолданылады. Сонымен бірге DLL файлының негізгі формасындағы функцияларды қосылған модуль функциялары секілді көрсетуге болады.

Мысал ретінде DataCheck динамикалық кітапханасының есептік кілттін қарастырайық:

 

library DataChek

uses

Windows, SysUtils, Classes, Messages, Forms,

Dialogs, StdCtrls, ComCtrls;

function ValidDate(AText: String): Integer; 

begin

try

Result := 0; StrToDate(AText); 

except

on E:EConvertError do Result := -1; 

end; 

end;

function ValidTime(AText: String): Integer;

begin 

try

Result := 0; StrToTime(AText);

except

on E:EConvertError do Result := -1; 

end; 

end;

function Validlnt(AText: String): Integer;

begin 

try

Result := 0; StrToInt(AText);

except

on E:EConvertError do Result := -1;

end;

end;

exports Validlnt,

ValidDate index 1, ValidTime index 2 name 'IsValidTime';

begin

if Length(DateToStr(Date)) < 10

then ShowMessage('Год представлен  двумя цифрами');

end.

 

Демек, бұл кітапхананың үш функциясы жолды ол нақты санға, уақытқа немесе күнге ауыспай тұрып оны тексеруді қамтамассыз етеді. Бұл функциялардың экспорттың қамтамассыз ету үшін оларды exports секциясында хабарлау керек.

Кітапхананың адрес, аты және реттік номерін компиляциялаған кезде экспортталатын функция DLL файлдағы арнайы экспорт кестесіне енгізіледі.

Шақыру туралы келісім. Динамикалық кітапханаларда процедуралар мен функцияларды хабарлау үшін әртүрлі шақыру туралы келісім қолданылады. Тек қана әртүрлі бағдарламалау тілдері процедураға параметрлерді енгізуді әртүрлі жағдайда іске асырады. Стектегі параметрлерді тексеру реті осы шақыру туралы келісіммен жүзеге асады.

C++ және Object Pascal тілдеріндегі стандартты шақыру ерекшелінеді, бірақ та типтерді өзгерту дерективаларының жиынтығы іске асыруды қамтамассыз етеді.

Процедура шақыратын барлық шақыру туралы келісімдерге стектегі параметрлер кедергі жасайды. Келісімнің типіне байланысты стекті тазалау шақырылатын және шақырылған процедура көмегімен жүзеге асады.

Егер стекті тазалау шақырылатын процедура көмегімен орындалса, онда ол одан қайтарылатын мәндерді алып үлгереді.

Егер стекті тазалау шақырылған процедура көмегімен жүзеге асса, онда ол одан бұрын қайтарылатын мәнге жадының уақытша облысында кедергі жасайды.

 

 

1.5 DLL - дегі ресурстар

 

 

Динамикалық кітапханалар тек қана шығарылатын кодтардан тұрмайды, олар сонымен қатар ресурстардан тұрады. Көп жағдайда процедура мен функцияның жұмысын қамтамассыз ететін DLL формалармен қоса тарату қажет болып тұрады. Динамикалық кітапхана проектілерінде формалармен жұмыс жасау тәсілдері қарапайым қосымша проектілеріндегі тәсілдерден еш айырмашылығы жоқ.

Тек қана жалғыз ерекшелігі DLL - дегі кез-келген форма автоматты түрде емес қолмен құрылған деп қаралуы тиіс. Сонымен бірге форма құратын процедурада болашақ форманың иесіне көрсеткіш жіберілуі керек. Мысалы, бізбен қарастырылып жатқан DataCheck кітапханасының showDemoForm процедурасы келесідей көрсетіледі:

procedure ShowDemoForm(AOwner: TComponent); 

begin

DemoForm := TDemoForm.Create(AOwner);

DemoForm.ShowModal;

DemoForm.Free; 

end;

Форманы өшіруді тек қана процедурада ұйымдастыруға болмайды. Сонымен қоса, басқа процедурада немесе динамикалық кітапхананы жүктегенде де болмайды.

Бұл процедураны қосымшаның параметрінен шақырған кезде қосымша классының экземплярын көрсету керек:

procedure ShowDemoForm(AOwner: TComponent); external 'DataCtrl.dll';

procedure TMainForm.BitBtnlClick(Sender: TObject); 

begin

ShowDemoForm(Application);

end;

Берілген жағдайда динамикалық кітапханадағы форма операциялық жүйеде жеке тапсырма ретінде қаралатындыына назар аударыңыз.

 

2. DELPHI ПРОГРАММАЛАУ  ОРТАСЫНДА DLL ДИНАМИКАЛЫҚ КІТАПХАНАЛАРЫН ҚҰРУ ЖӘНЕ ҚОЛДАНУ

 

2.1 DLL проектісі

 

 

Delphi репозиториясында динамикалық  кітапханаларды құру үшін арнайы  шаблон қолданылады. Оның белгісі New Репозитория бетінде орналасқан DLL Wizard. Проектінің қарапайым қосымшадан айырмашылығы DLL проектісі тек қана бір файлдан тұрады. Одан кейін оған жеке модульдер мен формалар қосуға болады. 2.1-суретте көрсетілген.

 

 

2.1-сурет. Delphi-де DLL құру үшін File -> New ->Other командасын орындау сұлбасы

 

 

2.2-сурет. File -> New ->Other командасын орындағаннан кейін ашылған DLL шеберін таңдау терезесі

 

Осы 2.1 - сурет және 2.2 – суреттерде көрсетілген қадамдардан кейін Delphi ұзақ комментарийлі арнайы проект терезесін ашады. Бұл терезеде ShareMem модуліне міндетті түрде өту керектігін көрсетеді. Бұл өту кітапхананың uses қосымшасында бірінші болуы керек. Егер кітапхананың қосымша бағдарламалары ShortString немесе Pchar жолдарын экспорттаса, онда ShareMem ға өту маңызды емес. Бұл жерде проектіні Сmpix деген атпен сақтау керек. Бұлай сақтау себебі Delphi кітапхана құрған кезде Library бөлімінде сол сақталған атпен автоматты түрде кітапхана құрады.

 

 

2.2 Динамикалық қосылатын кітапханалардың іске асуы

 

 

DLL жұмысқа дайын процедуралардан, функциялардан немесе ресурстардан  тұратын орындалатын модуль түрінде  іске асады. Бағдарламаушының көзімен қарағанда DLL және Object Pascal үшін қарапайым модульдер арасында көптеген сәйкестіктер бар. Кітапханаларда, модульдерде қосымша бағдарлама болып келеді. Олар тек бағдарламаушыны өзінің кодын жазуға жеңілдету үшін пайдаланатын болып шығады. Бірақ та принципті ерекшеліктері де кездеседі. Олардың негізгісі болып DLL - дің бағдарламаға енгізулер, константалар және типтер енгізу жағдайында болмауын жатқызуға болады. Себебі DLL құрушылары типизирлі бағдарламалау тілдерін қолдана алмайды. Ол тілдерге мысалға ассемблерді алуға болады. Сонында DLL бағдарламаға қазіргі кезде бағдарламаушыға керекті класстарды экспорттай алмайды. Осы жағдай үшін пакеттер қолданылады.

Object Pascal - да DLL - ді құру үшін Library деген сөз енгізілген. Бұл сөзбен кітапхана мәтіні басталуы керек. Library деген сөзден дұрыс идендификатор тұрады, бірақ модульді шақырудан айырмашылығы ол файл атымен сәйкес келмеуі керек: DLL аты идентификатормен емес DLL файл атымен анықталады.

DLL мәтінінің құрылымы  қарапайым бағдарламаның құрылымын  шектеулермен қайталайды. Ол шектеулерге DLL дегі орындалатын операторлар бөлімі инициалданатын модуль бөлімі орындайтын рөлді орындауы жатады. Модуль бөлімінің операторлары жадыға кітапхананы жүктеген кезде, 2.3 – суретте көрсетілгендей бір рет қана орындалады.

 

2.3-сурет. Жадыдағы DLL - дің құрылымы

 

DLL-ді сипаттау бөлімінде типтер (сонымен қоса класстарда), константалар және айнымалылар хабарлануы мүмкін, бірақ олар шақырылған бағдарлама үшін жасырын болып қала береді және DLL ішінде ғана қолданыла алады. Сипаттау бөлімінде  қарапайым бағдарламаға арналған стандартты шақырулардан басқа экспортталатын қосымша бағдарламалар үшін арнайы бөлім қолданылады. Бұл бөлім Exports сөзінен басталады және бұл сөзден кейін үтір арқылы экспортталатын қосымша бағдарламалар аттары жазылады. Мысалы:

library MyLibrary;

function MyFunc(...): ...;

begin

end;

procedure MyProc;

begin

end;

exports

MyFunc, MyProc;

begin

end.

Exports бөлімі кампиляторға және компоновщике DLL-модулі үшін арнайы тақырыбын құруға көмектеседі. Бұл модульде қосымша бағдарламалардың және олардың ену нүктелерінің адресстернің аттары жазылады. DLL-де  Exports тың бірнеше тізімі болуы мүмкін, бірақ ондағы жазылған қосымша бағдарламалар жоғарыда кітапхана мәтінінде сипатталуы керек.

DLL тақырыпшасындағы қосымша бағдарламалар атынан басқа оның реттік номері, яғни, оған арналған индексі де қосылады. Бұл шақырылған бағдарламаға қосымша бағдарламаға өту үшін онын аты емес индексі арқылы өтуді іске асырады. Және сонымен қоса онымен байланыс орнатуға кететін уақытты азайтуға да мүмкіндік береді. Индекс қосымша бағдарлама Exports тізімінде пайда болғаннан бастап беріледі: тізімдегі бірінші қосымша бағдарлама 0 деген индекске ие болады, келесісі - 1 және т.с.с. Бағдарлама құрушы бұл индексацияны өзгерте алады және қосымша бағдарламаларға индексін көрсете алады. Ол үшін ол Exports тізімінде онын атымен index деген сөзді енгізу арқылы және 0 - ден 32767 - ге дейінгі нақты сандарды белгілерсіз енгізу арқылы қосымша бағдарлама индексін өзгерте алады:

exports

MyFunc index 1, MyProc index 2;

Бағдарламашы экспортталатын бағдарламаның негізгі атынан айырып тұратын сыртқы атын сипаттай алады. Бұл үшін Exports тізіміне name және сыртқы ат тырнақша ішінде жазылуы арқылы енгізуге болады:

exports

MyFunc index I name 'NEWFUNC';

Шақырылатын бағдарлама экспортталатын қосымша бағдарлама атына немесе онын индексіне өте алады. Аты арқылы шақырған кезде бағдарлама кесте ішінен ізделінетін атқы сәйкес ат іздейді. Аттардың ұзақ символдардан тұруы және бірдей аттардың кестеде көп болу мүмкіншілігіне байланысты аты арқылы іздеу процессі индекс арқылы іздеу процессіне қарағанда жай болады. Сондықтан дәрежелі бағдарламаушылар қосымша бағдарламаларға аты арқылы емес индексі арқылы өтуді таңдайды.

Қарап отырсаңыз, Delphi дің модульдерден айырмашылығы олар DLL ді make немесе build, т.с.с. автоматты режимдерінде компилациядан өткізбейді. Мысал

DLL-ді құру мысалын қарастырып кетейік, бұл мысалда экспортталатын қосымша бағдарламаларды хабарлаудың әртүрлі тәсілдері құрылады. Мысал үшін cmpix модулін таңдайық. Оның құрамына төрт процедура кіреді. DLL-ге сәйкес келетін нұсқа төменде көрсетілген.

library Cmpix;

uses

SysUtils, Classes;

{$R *.RES}

type

TComplex = record Re, Im: Real;

end;

function AddC(x, y: TComplex): TComplex; stdcall;

begin

Result.Im := x.Im + y.Im;

Result.Re := x.Re + y.Re

end;

function SubC(x, y: TComplex): TComplex; stdcall;

begin

Result.Im := x.Im - y.Im;

Result.Re := x.Re - y.Re

end;

function MulC(x, у: TComplex): TComplex; stdcall;

begin

Result.Re := x.Re * y.Re + x.Im * y.Im;

Result.Im := x.Re * y.Im - x.Im * y.Re

end;

function DivC(x, y: TComplex): TComplex; stdcall;

var

z: Real;

begin

z := sqr(y.Re) + sqr(y.Im);

try

Result.Re := (x.Re * y.Re + x.Im * y.Im) / z;

Result.Im := (x.Re * y.Im - x.Im * y.Re) / z

except

Result.Re := le + 309;

Result.Im := le + 309

end

end;

exports

AddC index 1 name 'ADDC' resident,

SubC index 2,

MulC index 3,

DivC index 4;

begin

end.

Бұл жерде назар аударатын жағдай DLL - дің барлық функциялары stdcall келісімін пайдаланады. Бұл келісім жаңа функциялардың API Windows 32 функцияларыменен сәйкес келулерін қамтамассыз етеді. Біз бұл келісімді көрсетпей кетуімізге де болатын еді. Бірақ бұл жағдайда компилятор бұл келісімнен мықтырақ келісім register келісімін пайдаланар еді, бірақ біздің DLL-ді басқа бағдарламалау тілдерінде жазылған бағдарламадан шақыру жалпы жағдайда мүмкін болмай кетер еді.

Егер сіз DLL - ді «сыртқы» жағдайда (Delphi - ден тыс), қолдану үшін құрсаңыз, онда қосымша бағдарламаларды stdcall немесе safecall директиваларымен хабарлаңыз.

Қолданылуы. Статикалық жүктеу. Келесі бағдарламада Сmpix кітапханасы қолданылады. Бұл кітапхана алдыңғы беттерде сипатталып кеткен.

type

TComplex = record

Re, Im: Real;

end;

function ADDC(x, y: TComplex): TComplex; stdcall; external 'Cmplx';

function SubC(x, y: TComplex): TComplex; stdcall; external 'Cmplx';

function MulC(x, y: TComplex): TComplex; stdcall; external 'Cmplx';

function DivC(x, y: TComplex): TComplex; stdcall; external 'Cmplx';

procedure TfmExample.bbRunClick(Sender: TObject);

var

x, y, z: TComplex;

cmpixAdd кітапханалық функциясы addc сыртқы атына ие болатынына  назар аударған жөн. Дәл осылай  жоғарыдағы мысалда бұл функция  сипатталған. Егер біз келесідегілерді  қолдансақ, онда компоновщик оны  идентифициралмайтын еді.

function AddC(x, у: TComplex): TComplex; stdcall; External

'Cmplx';

Динамикалық жүктеу. Жоғарыда көрсетілген DLL функциялары мен процедураларын анықтау (External  директиваларының көмегімен) тәсілі компиляторды бағдарламалар тақырыпшасына барлық  DLL-ді орналастыруды талап етеді. Бағдарлама External директивасысыз DLL-ді үш стандартты функция көмегімен жүктей алады.

Ол стандартты функциялар: LoadLibrary, GetProcAddress және FreeLibrary.

Келесі мысалда DLL Cmplx ті осындай техникамен жүктеу көрсетілген:

type

TComplex = record

Re, Im: Real;

end;

TComplexFunc = function(x, y: TComplex): TComplex; stdcall;

procedure TfmExample.bbRunClick(Sender: TObject);

var

x, y, z: TComplex;

AddC, SubC, MulC, DivC: TComplexFunc;

Handle: LongWord;

procedure Output(Operation: Char);

// Output  процедурасының денесі өзгеріссіз қалады

end; //Output

begin //bbRunClick

// CMPLX.DLL Handle := LoadLibrary('Cmplx.dll') кітапханасын  жүктейміз;

if Handle = 0 then

begin

ShowMessage('CMPLX.DLL кіиапханасы  табылмады');

Halt

end;

{Функциялардың адресстерін анықтаймыз. Алғашқы үшеуін индексі арқылы шақырамыз, төртіншісін – аты арқылы, индексі арқылы шақырған кезде Pchar сөзі индекстен тұруы керек, сондықтан алдымен типтерді анықтауды жасаймыз: }

 

@AddC := GetProcAddress(Handle, PChar(Longint(1)));

PSubC := GetProcAddress(Handle, PChar(Longint(2)));

@MulC := GetProcAddress(Handle, PChar(Longint(3)));

@DivC := GetProcAddress(Handle, 'DivC');

x.re := Random;

x.im := Random;

y.re := Random;

y.im := Random;

Output('+');

Output('-');

Output('*');

Output('/');

mmOutput.Lines.Add('');

// FreeLibrary(Handle) кітапханасын босатамыз

end;

 

 

2.3 Интерфейстік модуль

 

 

DLL- қосымша бағдарламаларды  шақырған кезде көптеген жағдайда  жазбалардың типтеріне алғашқы мысалдағы Tcomplex типі секілді құрылымдық параметр беру міндетті болады. DLL типтерді экспорттай алмайтындықтан бұл типтерді шақырылған бағдарламада хабарлау керек. Егер сіз өздеріңіздің бағдарламаңызда сол немесе басқа DLL - ге жиі қолдансаңыз, онда интерфейстік модуль құрған сізге ыңғайлы болады. Бұл модуль қосымша бағдарламалар мен оларға байланысқан типтерді хабарлайды. Мысалы:

unit Complx;

interface

type

TComplex = record

Re, Im: Real;

end;

function AddC(x, y: TComplex): TComplex; stdcall; External 'Cmplx' index 1;

function SubC(x, y: TComplex): TComplex; stdcall; External 'Cmplx' index 2;

function MulC(x, y: TComplex): TComplex; stdcall; External 'Cmplx' index 3;

function DivC(x, y: TComplex): TComplex; stdcall; External 'Cmplx' index 4;

implementation

end.

Мұндай интерфейстік модуль негізгі бағдарламаны өндеуді оңайлатыды: біздің мысалда ол cmpix кітапханасына дәл осындай интерфейспен қамтамассыздандырады.

 

 

2.4 DLL құру барысында туындайтын шектеу жағдайлар

 

 

Delphi де құрылған DLL-дегі туындайтын шектеулі жағдайлар барлық қосымшалардың іске асуын тоқтатуға әкеп соғады. Бұл жағдайлар DLL-дің ішінде өнделмеген болған жағдайда. Сондықтан DLL-ді құрған кезде барлық мүмкін болатын қателіктерді қарастырып кеткен жөн. Импортталатын функцияның жол немесе сан түріндегі іске асқан шешімін қайтаруды ұсынуға болады және де керек болған жағдайда бағдарламадағы шектеулі жағдайларды қайтадан шақыруға болады.

DLL-дегі код:

function MyFunc : string;

begin

try

{собственно код функции}

except

on EResult: Exception do

Result:=Format(DllErrorViewingTable,

[EResult.Message]);

else

Result := Format(DllErrorViewingTable,

['Unknown error']);

end;

end;

Бағдарламадағы код:

StrResult:=MyFunc;

if StrResult<>'' then

raise Exception.Create(StrResult);

 

2.5 DLL -ді қолдану аймақтары

Динамикалық кітапханалар