int21h

Dynamické knihovny v pascalu

Microsoft není ta společnost, která dynamická knihovny navrhla, ale je to ta společnost, která je jako první začala využívat.
Budeme potřebovat BP 7.0, ve kterém je obsazen RTM.EXE a vrstva (overlay) DPMI16BI.OVL. Ta slouží jako extender, který umožní přepnutí z 16-ti bitového Real Módu do 32-bitového Protected Módu.
Po spuštění pascalu si pak z menu zvolíme Compile->Target->Protected

Tvorba dynamické knihovny

Vše si vysvětlíme na příkladě:
První soubor
============

Library MojeDLL;
Procedure ClrScr; Export; Assembler;
Asm
Mov Ax, 03h
Int 10h { nastavi rezim $3h (80x25 radku) a vycisti videopamet (nachazejici se na segB000) }
End;


Function Pozdrav : String; Export; { Neni mozne pouzit primo WriteLn, protoze standardni vystup je presmerovan }
Begin
Pozdrav := 'Hello world !';
End; { Exportovane funkce, ktere bude mozne importovat v jinych aplikacich }


Exports ClrScr;
Exports Pozdrav;
{ ------------------------------------------------------------------- }  
Uložit pod názvem mojedll.pas a pomocí F9 (BUILD) sestavit. Tím nám vznikne soubor mojedll.dll

Druhý soubor
============

{ Importy }
Procedure ClrScr; Far; External 'MojeDLL';
Function Pozdrav : String; Far; External 'MojeDLL';
{ ------- }
Begin
ClrScr;
WriteLn (Pozdrav);
End.  
Jak to chodí v praxi
====================
Tento postup je vždy funkční, ale první komplikace nastávají v případě, že chceme, aby nase knihovna vypisovala přímo na obrazovku. Řešit to lze například takto:

Prvni soubor
============

Library MojeDLL;
Uses Crt;
...
Procedure Pozdrav; Export;
Var F : Text;
Begin
AssignCrt (f);
ReWrite (f);
WriteLn (f, 'Hello world !');
Close (f);
End;
...  

Druhý soubor
============

Procedure Clear; Far; External 'MojeDLL';
Procedure Pozdrav; Far; External 'MojeDLL';
Begin
Clear;
Pozdrav;
End.

Nevýhody
========

Pochopitelně nelze číst obsah proměnných z knihoven, protože proměnné jako takové se nemohou exportovat. Řešení může, ale nemusí spočívat ve funkci, která vrací obsah proměnné. Funkci totiž exportovat můžeme. Pokud budeme v jedne knihovne importovat funkce z druhé knihovny a ve druhé knihovně importovat funkce z první knihovny, pak nám program nebude fungovat v IDE Borland Pascalu.
Jde o to, že si ho v IDE zkompilujeme, spustíme a podruhé už pod IDE spustit nepůjde. V DOSu však můžeme takovýto program spustit kolikrát chceme a žádný problém s knihovnami nebude.
Dále jsem narazil na to, že takto zacyklené knihovny nelze zkompilovat pomoci BPC.EXE, protože ten kompiluje jinak, než kompilátor zahrnutý v IDE. Prakticky jediná možnost je tedy využít IDE, které ma implementován kompilátor přímo v sobě.
Další nevýhodou je ono přesměrování standardního výstupu, ale to lze bez problému obejít vlastním WriteLn, postaveném na ah=09h; Int 21h;

Výhody
======

Programoval jsem si dynamickou knihovnu grafika.dll a ta má za úkol provádět veškerý výstup na obrazovku v High Color / True Color či 256 barevném módu. Žádné problemy s ni nebyly a ušetřila mi spoustu místa na disku i zbytečných rekompilací programů, které pracují v grafice. Velmi dobré je naprogramovat si třeba vesa.dll, mouse.dll, sound.dll, hdd.dll, cdrom.dll, math.dll, memory.dll, misc.dll a pak vlastně už nepoužívat žádné pomalé standardní unity BP, ale pouze ty své vlastní knihovny, které mohou být maximálně optimalizované pomocí assembleru. Čili tímto způsobem už nemusíte aktualizovat svůj program (jeho EXE soubor), ale pouze jednotlivé knihovny, které si napíšete.
Další dobré využití spočívá v uskladnění zdrojů (resources), protože si je můžete do knihovny zapsat stejně, jako do obyčejných unitů.
Slouží k tomu direktiva kompilátoru {$L nazev_souboru}.
Soubor pak musí být převeden do formátu OBJ. K tomu slouží bin2obj.exe, který je standardní součástí Borland Pascalu 7.0, ale předpokládám, že ho najdeme i v nižších verzích a tam už by mohla nastat nekompatibilita, čili si dávejte pozor na to, v jaké verzi zrovna pracujete.
Více podrobností ohledně přilinkování souboru do EXEcutable najdete v nápovědě pascalu pod oznacenim $L.
2006-12-12 | --==[FReeZ]==--
Reklamy: