Limbajul Pascal abc-doar


formula doua sau mai multe variante de compilare a datelor din aceeasi



Yüklə 2,15 Mb.
səhifə23/24
tarix03.11.2017
ölçüsü2,15 Mb.
#28851
1   ...   16   17   18   19   20   21   22   23   24

formula doua sau mai multe variante de compilare a datelor din aceeasi

unitate sursa.Nu este bine,totusi,sa abuzati de prea multe directive de

acest gen,sau sa formulati bucle de selectie a datelor prea complicate,

deoarece unitatile vor fi incomprehensibile pentru alti programatori care

ar fi eventual interesati sa le utilizeze.Este bine ca atunci cand decla-

rati o unitate noua,sa aveti in vedere faptul sa ar putea sa fie utila si

pentru alte programe,sau alti utilizatori.In acest sens,este bine ca

datele declarate sa fie incluse in constante si variabile cu denumiri cat

mai discriminative (se vor evita identificatorii de tip x,y,a,b,c etc si

se vor prefera cei de tipul: variabilax1,variabilax2 etc.) astfel incat

sa se evite pe cat posibil conflictul de nume cu eventualele constante si

variabile din programul care apeleaza unitatea.

Buclele de compilare conditionala pot fi utilizate cu succes pentru

a selecta din unitatile declarate de altii,doar un fragment,cel care este

util in programul d-voastra.Astfel,se economiseste munca de programare

si memoria de operare.Reciproc,trebuie ca unitatile declarate de d-voastra

sa poata fi apelate conditional de catre alti utilizatori (datele trebuie

sa fie clare,expresiile cat mai simple si cat mai usor de evaluat,etc.).


-189-

Pentru a forma biblioteci,doua sau mai multe unitati se grupeaza cu uses:

EXEMPLU: unit unit9;

INTERFACE

uses WinCRT,WinProcs,WinTypes;

var w,h,nr,b:integer;

t1,t2,t3:longint;

IMPLEMENTATION

begin

Randomize;

InitWinCRT;

w:=GetActiveWindow;

h:=GetDC(w);

t1:=GetCurrentTime;

repeat

b:=CreateSolidBrush(RGB(Random(255),Random(255),Random(255)));

SelectObject(h,b);

Ellipse(h,100,100,200,200);

t2:=GetCurrentTime;

repeat

t3:=GetCurrentTime;

until t3>t2+1000;

until t2>t1+10000;

end.

Unitatea poate fi apelata cu un program de genul:

EXEMPLU: program prog9;

uses unit9;

begin

end.

Si o a doua unitate similara (in exemplu este derivata din prima):

EXEMPLU: unit unit10;

INTERFACE

uses WinCRT,WinProcs,WinTypes;

var w1,h1,nr1,b1:integer;

t11,t21,t31:longint;

IMPLEMENTATION

begin

Randomize;

InitWinCRT;

w1:=GetActiveWindow;

h1:=GetDC(w1);

t11:=GetCurrentTime;

repeat

b1:=CreateSolidBrush(RGB(Random(255),Random(255),Random(255)));

SelectObject(h1,b1);

Rectangle(h1,350,100,450,200);

t21:=GetCurrentTime;

repeat

t31:=GetCurrentTime;

until t31>t21+1000;

until t21>t11+10000;

end.


-190-

Cea de a doua unitate se poate apela cu:

EXEMPLU: program prog10;

uses unit10;

begin

end.
Pentru a utiliza ambele unitati se poate scrie un program de genul:

EXEMPLU: program prog11;

uses unit9,unit10;

begin

writeln('Sfarsitul compilarii celor doua unitati !');

writeln('Incepe programul propriu zis...');

end.

Pentru a forma o biblioteca,cele doua unitati pot fi grupate intr-o sin-

gura unitate,care le apeleaza pe amandoua in etapa de INTERFACE,prin

instructiunea uses.

EXEMPLU: unit unit11;

INTERFACE

uses unit9,unit10;

IMPLEMENTATION

begin

end.

In continuare,pentru a utiliza cele doua unitati este suficient sa fie

apelata biblioteca care le cuprinde pe amandoua:

EXEMPLU: program prog12;

uses unit11;

begin

end.

In mod similar se pot grupa un numar mai mare de unitati,pentru a forma

biblioteci mai complexe.In exemplele de mai sus,unitatile executa si o

serie de operatii in etapa de initializare,pentru a evidentia cat mai

clar de unde si pana unde dureaza compilarea fiecarei unitati (prima ge-

nereaza cercuri colorate aleator,iar cea de a doua genereaza patrate.

Observati ca unitatile apelate se incarca o singura data in memorie si

orice apel ulterior suprascrie acelasi fragment de memorie:

EXEMPLU: program prog13;

uses unit9,unit10,unit11;

begin

end.

este identic cu prog12.Ca rezultat,unitatile pot fi apelate ori de cate

ori este necesar fara riscul de a supraincarca memoria prin rescrierea

acelorasi unitati.Totusi,este preferabil ca fiecare unitate sa fie apelata

o singura data,deoarece repetitia iterativa introduce operatii inutile

care cresc nejustificat uzura aparaturii.In plus,este bine ca fiecare

programator sa tina o evidenta cat mai stricta a memoriei consumate.Daca

va bazati doar pe sistem in gestiunea memoriei,mai devreme sau mai tarziu

puteti avea si surprize neplacute.

Gruparea unitatilor sub forma de biblioteci,adauga putina eleganta in

munca de ordonare a datelor si formeaza un obicei bun.In mod similar,in

cazul bibliotecilor alocate dinamic (DLL),toate functiile importate din

biblioteci diferite se pot grupa intr-o biblioteca(unitate) de import.


-191-

BIBLIOTECILE ALOCATE DINAMIC (DLL)
Bibliotecile alocate dinamic,denumite prescurtat DLL(dynamic link li-

braries),sunt asemanatoare cu cele statice dar au cateva particularitati.

Orice biblioteca DLL incepe cu cavantul cheie library (in loc de unit sau

program) care determina compilatorul sa genereze o fila cu extensia .dll.

Asa cu le spune si numele,aceste biblioteci nu sunt incarcate in memorie

in momentul compilarii programului ci doar in momentul executiei.

Principalul scop al acestor biblioteci este de a permite mai multor

programe si aplicatii sa utilizeze acelasi set de date sau aceleasi coduri

functii si proceduri sau chiar obiecte.O biblioteca DLL este un modul

executabil,independent si poate contine pe langa coduri si resurse proprii

(gen icoane,cursoare,arii bitmap,tabele etc.).Prezenta bibliotecii este

obligatorie atunci cand un program apeleaza o astfel de biblioteca.Astfel,

daca intr-un program exista functii declarate EXTERNAL,care importa defi-

nitia dintr-o fila de tip .dll,este obligatoriu ca fila .dll sa fie pre-

zenta in momentul compilarii,chiar daca nu va fi incarcata in memorie si

nu va fi utilizata in cursul executiei programului(functiile raman neape-

late).Aceasta este si principala deficienta introdusa de utilizarea unor

astfel de biblioteci (daca se sterge din greseala una dintre bibliotecile

DLL apelate,programul respectiv nu mai poate fi utilizat).

In schimb,actualizarea sau modificarea unei file DLL va atrage dupa sine

actualizarea tuturor programelor si aplicatiilor care utilizeza fila res-

pectiva.In plus,bibliotecile DLL nu consuma din memoria de operare si nu

sunt incarcate in memorie decat strict functiile apelate si doar in mo-

mentul in care sunt apelate.

Spre deosebire de bibliotecile statice,bibliotecile DLL nu exporta

toate datele ci doar pe cele specificate expres prin cuvantul cheie

EXPORT si respectiv incluse in lista de export introdusa cu ajutorul

cuvantului cheie EXPORTS.Asadar,o biblioteca DLL poate contine atat date

interne (care pot fi apleate doar in interiorul filei DLL) cat si date

(functii,proceduri,obiecte) care pot fi exportate in alte module.

Toate variabilele globale dintr-o fila DLL sunt strict interne si nu

pot fi exportate.Clasic,bibliotecile DLL exporta doar functii si proce-

duri,dar se poate apela la un mic artificiu prin care o functie oarecare

returneaza o valoare de tip obiect,caz in care obiectul respectiv poate

fi exportat.

Legatura(link) dintre programul apelant si fila DLL care contine defi-

nitia functiilor exportate se face in momentul compilarii programului (

chiar daca incarcarea in memorie se va face doar in momentul executiei !).

Bibliotecile DLL pot fi partajate nu doar de catre utilizatori si pro-

grame diferite scrise in Pascal,dar pot fi utilizate si de catre programe

scrise in alte limbaje (C si C++,Delphi,Oracle,Visual Basic etc.) cu

conditia sa utilizeze aceleasi conventii de apel si respectiv sa contina

doar functii comune pentru ambele limbaje (de exemplu functiile Windows).

Principalele conventii de apel sunt:REGISTER,CDECL,STDCALL,SAFECALL si

PASCAL.Register,este conventia implicita si transfera parametrii de la

dreapta la stanga in timp ce CDECL,STDCALL si SAFECALL transfera para-

metrii de la stanga la dreapta.CDECL se utilizeaza in bibliotecile DLL

scrise in C si C++ iar STDCALL si SAFECALL sunt utile mai ales pentru

cele care contin functii Windows API.


-192-

O biblioteca DLL se editeaza la fel ca un program obisnuit,dar se

incepe cu cavantul cheie library urmat de numele bibliotecii(identificator)

Functiile si procedurile care urmeaza sa fie exportate se specifica expres

adaugand cuvantul cheie EXPORT la sfarsitul declaratiei,iar la sfarsitul

etapei de implementare se adauga un modul de export care incepe cu cuvant-

ul cheie EXPORTS si continua cu lista functiilor si procedurilor exportate

EXEMPLU:

library bibdll1;

function Mesaj:PChar;export;

begin

mesaj:='Text preluat din biblioteca bibdll1';

end;

exports

Mesaj;

begin

end.

Utilizarea bibliotecii se poate face cu un program de genul:

EXEMPLU:

program progdll1;

uses WinCRT;

function Mesaj:PChar;external 'bibdll1';

begin

writeln(mesaj);

end.

Observati ca pentru a importa functia dorita din fila DLL,am utilizat

cuvantul cheie external,urmat de numele bibliotecii(identificatorul).

Este foarte simplu !

Atunci cand biblioteca contine un numar mai mare functii care urmeaza

sa fie exportate,se poate adauga un index pentru a identifica mai usor

fiecare functie (mai ales in etapa de depanare a programului).

EXEMPLU:

library bibdll2;

function Min1(x,y:integer):integer;export;

begin

if x

end;

function Max1(x,y:integer):integer;export;

begin

if x>y then Max1:=x else Max1:=y;

end;

exports

Min1 index 1,

Max1 index 1;

begin

end

Observati ca in modulul de export,cele doua functii exportate au primit si

un numar de indexare cu ajutorul caruia pot fi identificate mult mai

discriminativ.Clauza de indexare este facultativa iar numarul de indexare

poate fi orice numar de tip unsigned int (1-32767).Daca nu se specifica

numarul de indexare,functia va avea un numar de ordine atribuit automat.

In continuare,cele doua functii vor putea fi apleate prin indexul lor:


-193-

EXEMPLU:

program progdll2;

uses WinCRT;

function Min1(x,y:integer):integer;external 'bibdll2' index 1;

function Max1(x,y:integer):integer;external 'bibdll2' index 2;

begin

writeln('minima dintre 19 si 3 este: ',Min1(19,3));

writeln('maxima dintre 99 si 7 este: ',Max1(99,7));

end.

Asadar,cele doua functii pot fi apelate atat prin numele lor (la fel

ca in primul exemplu),cat si prin numarul lor de indexare.A treia modali-

tate de a importa o functie este prin utilizarea unui nume nou fata de

cel initial(functia importata va fi redenumita prin noul identificator).

La prima vedere pare putin confuz si complicat,conform cu aforismul:

" That which is static and repetitive is boring

That which is dynamic and random is confusing

In between lies art !

John A.Locke "

Pentru a evita o mare parte din confuziile posibile,este de dorit ca

atunci cand editati biblioteci DLL pe care doriti sa le poata utiliza si

alti programatori,sa adaugati pe langa fila de explicatii,si fila de cod

sursa,cu extensia .PAS(cea care a fost compilata pentru a genera fila DLL)

Ratiunile sunt aceleasi ca si pentru unitati.In plus,bibliotecile de tip

DLL pot fi utilizate modular (utilizatorul poate alege singur functiile

pe care doreste sa le importe).Fara fila sursa este putin probabil ca

munca d-voastra sa fie utila si altor programatori.In caz ca scrieti

programe comerciale si jocuri,caz in care doriti sa pastrati secretul

codurilor si sa valorificati material munca depusa,puteti sa puneti la

dispozitie doar fila gata compilata si un sumar de explicatii si recoman-

dari,cu speranta unor castiguri viitoare (personal nu cunosc nici un mili-

onar cu bani produsi din DLL-uri).

O procedura se editeaza si exporta la fel ca si o functie.Este reco-

mandabil sa utilizati doar majuscule sau doar minuscule atunci cand

formulati numele procedurii (Exemplu: MESAJ sau mesaj in loc de Mesaj).

EXEMPLU:

library bibdll3;

uses WinCRT,WinProcs,WinTypes;

var x:integer;

procedure mesaj;export;

begin

x:=messagebox(GetActiveWindow,'Bun gasit ...DLL','mesaj',MB_OK);

end;

exports

mesaj index 1;

begin

end.

Editarea respecta aceleasi reguli ca si in cazul unitatilor.Conventiile

de limbaj sunt aceleasi.Diferenta este data de faptul ca o biblioteca

DLL poate contine si coduri interne,care nu vor fi accesibile in programul

apelant.De exemplu,variabila x din acest program nu va putea fi preluata

sau apelata in programul sau aplicatia care utilizeaza aceasta fila.


-194-

Fila DLL descrisa anterior poate fi apelata cu un program de genul:

EXEMPLU:

program progdll3;

uses WinCRT,WinProcs,WinTypes;

procedure mesaj:external 'bibdll3' index 1;

begin

InitWinCRT;

mesaj;

end.

In momentul apelului unei proceduri externe,aceasta poate sa apeleze

si procedurile interne din fila DLL (daca este cazul),inainte de a retur-

na executia la programul apelant.De exemplu,mesajul de mai sus poate fi

continut intr-o procedura interna (care nu este exportata) dar va fi pre-

luat cu ajutorul unei functii exportate:

EXEMPLU:

library bibdll4;

uses WinCRT,WinProcs,WinTypes;

var x:integer;

procedure text;

begin

x:=MessageBox(GetActiveWindow,'Bun gasit ...DLL','mesaj:',MB_OK);

end;

procedure mesaj;export;

begin

text;

end;

exports

mesaj index 1;

begin

end.

Pentru apelul functiei se va utiliza un program similar cu progdll3:

EXEMPLU: program progdll4;

uses WinCRT,WinProcs,WinTypes;

procedure mesaj;external 'bibdll4' index 1;

begin

InitWinCRT;

mesaj;

end.

Diferenta fata de fila DLL precedenta este data de faptul ca procedura

mesaj (cea exportata) apeleaza la o procedura interna (procedura text),

inainte de a returna executia la programul apelant.In mod similar,pro-

cedurile din fila DLL se pot apela intre ele,ori de cate ori este necesar

inainte de a returna controlul la fila apelanta.Atentie maxima insa,sa nu

ramana nici un proces in executie inainte de a returna controlul catre

fila apelanta.In caz contrar,procesul respectiv va ramane in executie in

background si va parazita memoria de operare pana la oprirea calculato-

rului(spre deosebire de procesele neterminate din fila de program,care se

vor intrerupe automat in momentul inchiderii programului.Orice stream

ramas deschis si orice obiect neeliberat din memorie va determina un

proces parazitar,redundant,care blocheaza memoria de operare (programul

respectiv nu va mai putea fi lansat decat dupa inchiderea calculatorului).

-195-

Filele DLL se pot utiliza si pentru aplicatiile grafice.Functiile si

procedurile se definesc la fel ca si in programe,dar cu atentie maxima

la eliberarea obiectelor definite si a variabilelor de tip handle:

EXEMPLU:

library bibdll5;

uses WinCRT,WinProcs,WinTypes;

var x:integer;

procedure desen;export;

begin

x:=GetDC(GetActiveWindow);

TextOut(x,50,10,'Aplicatie grafica:',18);

MoveTo(x,50,50);

LineTo(x,50,250);

LineTo(x,250,250);

Rectangle(x,100,100,200,200);

Ellipse(x,120,120,180,180);

ReleaseDC(GetActiveWindow,x);

end;

exports

desen index 1;

begin

end.

Fila DLL descrisa mai sus poate fi apelata cu:

EXEMPLU: program progdll5;

uses WinCRT,WinProcs,WinTypes;

var x:integer;

procedure desen;external 'bibdll5' index 1;

begin

InitWinCRT;

desen;

exit;

end.

In exemplul de mai sus,daca se omite eliberarea variabilei handle x,in

care am stocat codul pentru contextul de dispozitiv (cu GetDC() ),atunci

procesul respectiv va ramane stocat in memorie si va bloca relansarea

programului (returneaza un mesaj de eroare nedeterminat).

Pentru a evita astfel de erori,verificati cu foarte mare atentie

fiecare element la filelor DLL.Executati fiecare functie exportata de

mai multe ori si verificati cu atentie si memoria ramasa libera in urma

executiei.Orice greseala,oricat de mica,la nivelul unei biblioteci de

functii DLL se va rasfrange asupra tuturor programelor si aplicatiilor

care apeleaza biblioteca respectiva.Astfel,daca in etapa de actualizare

a unei biblioteci DLL introduceti o eroare de executie,aceasta va bloca

toate aplicatiile linkate la fila respectiva.

Din acest motiv,nu este bine sa utilizati biblioteci DLL la care nu

aveti acces la fila de coduri.Daca biblioteca nu este insotita de fila

.PAS si daca nu detineti un program care face conversia inversa,(din fila

executabila in fila .PAS)este mai bine sa nu utilizati filele DLL scrise

de altcineva,decat strict pentru scopul pentru care v-au fost livrate.

In situatii disperate,inlocuiti functia exportata cu una redefinita.


-196-

Daca utilizati o biblioteca DLL in comun cu alti utilizatori,si nu

stiti exact in ce alte aplicatii este apelata,nu incercati sa faceti

actualizari ale filei,deoarece dernajati sau chiar invalidati aplicatiile

celorlati utilizatori.Pentru filele utilizate in retea,toate actualizarile

si modernizarile sunt rezervate administratorului de retea.

La fel ca si in cazul unitatilor,se poate utiliza si blocul de initia-

lizare situat in interiorul buclei begin ... end.In acest caz,toate co-

mezile si instructiunile din acest compartiment se vor executa in etapa

de compilare (ca si in cazul unitatilor,legatura dintre aplicatie si

fila DLL=linkarea,se face in etapa de compilare).

EXEMPLU:

Yüklə 2,15 Mb.

Dostları ilə paylaş:
1   ...   16   17   18   19   20   21   22   23   24




Verilənlər bazası müəlliflik hüququ ilə müdafiə olunur ©muhaz.org 2024
rəhbərliyinə müraciət

gir | qeydiyyatdan keç
    Ana səhifə


yükləyin