Személyes eszközök
Keresés

 

A InfoWiki wikiből



Tartalomjegyzék

Az Assembly (DLL)

Amikor egy nagyobb programot készítünk, gyakori, hogy nem minden részét egyedül készítjük. Felhasználhatjuk saját cégünknél dolgozó más programozók munkáját, saját korábbi projectjeink kódjait, de akár más, külső cégek programozóinak kódjait is.

Amikor Windows programot írunk, akkor például erősen támaszkodunk a Microsoft programozóinak munkájára - hiszen a programunk ablakos felületével kapcsolatos kódokat nem mi írjuk, hanem hivatkozunk a Windows mint operációs rendszer kódrészeire.

Az egyik legjobb módszer más programozók kódjainak felhasználására a 'DLL'-ek használata.

A 'DLL'-ek (Dynamic Link Library) olyan file-ok, melyek lefordított kódot tartalmaznak. Az egyik leglényegesebb különbség az 'EXE' (Executable) és a 'DLL' között, hogy ez utóbbi önállóan nem futtatható file, ugyanis jellemzően nem tartalmaz 'Main()' függvényt.

Win16 és Win32 DLL

A 'DLL' technológia már igen régen használatban van a Windows operációs rendszereken. A Windows 3.1-es verziójával már rengeteg '.dll' file települt fel a gépünkre. Az újabb verziójú, 32 bites Windows-okkal érkező '.dll'-ek is igen hasonló belső szerkezettel, és felhasználási területtel rendelkeznek.

Ezen '.dll' file-ok belsejében függvények találhatóak, melyeket bármilyen más program elvileg használhat a saját kódjának kiegészítéseképpen. Vagyis a program írása során is ezen függvényekre hivatkozik, melyek már meg vannak írva, le vannak tesztelve. Egy ilyen '.exe' file e miatt egyrészt kisebb méretű lesz (kódhossz-csökkentés), de futásához szükséges (értelemszerűen), hogy a célgépen is ott legyen a hivatkozott '.dll' file.

Egy apró problém van ezekkel a '.dll' file-okkal: tartalmuk nem önleíró! Vagyis legfeljebb az deríthető fel egy "ismeretlen" dll file esetén, hogy milyen "nevű" függvények találhatóak benne. De sem a függvények paramétereiről, sem a visszatérési érték típusáról, sem magáról a függvény által elvégzett feladatról nem tartalmaz információt (ez utóbbira a függvény nevéből lehet esetleg következtetni). A fentieken túl azt sem lehet tudni, hogy a függvény milyen módon jelzi a hibás működést, milyen hibakódokat adhat vissza, és melyiknek mi a jelentése, stb.

Természetesen amennyiben nem csak maga a '.dll' file, hanem annak dokumentációja is rendelkezésre áll (esetleg kis példaprogramokkal megtámogatva), úgy a helyzet egészen más: akkor a '.dll' file-t könnyedén be tudjuk illeszteni a saját programunkba.

Problémák: a fentieken túl állandó problémát jelentett, hogy a Win32 DLL-ek esetén ismerni kellett azt is, hogy az adott DLL mely programozási nyelven készült. Ugyanis a különböző nyelvek eltérő módon vagy bithosszon ábrázolták a különböző egyszerű adattípusokat (integer, double), de legfőképpen különböztek a string-ek ábrázolásában. Összetett adattípusokkal (vektor, rekord) még több problémára lehetett számítani. Ezért jellemző volt, hogy egy adott DLL-t csak ugyanazon a programozási nyelven készülő projectben lehetett problémamentesen felhasználni.

.NET DLL

A helyzet sokat változott a .NET esetében. Az itteni '.dll'-ek csak funkcióban hasonlítanak a fentiekben ismertetett Win32 (natív) dll-ekre. A .NET DLL-jei ...

  • nem függvényeket, hanem osztályokat, általánosabban típusokat tartalmaznak. Ezen osztályok metódusokat, mezőket, property-ket tartalmaznak. A saját kódunkban a DLL-ben lévő osztályszintű metódusokat közvetlenül hívhatjuk meg. De van lehetőség az osztályok példányosítására, így a példányszintű metódusokat is használhatjuk. De arra is van mód, hogy saját kódunkban egy, a DLL-ben definiált osztályból gyermekosztályt készítsünk.
  • önleíróak: vagyis egy ilyen DLL-ben lévő névterek, osztályok, azokban lévő mezők, metódusok nevei, típusai, esetleg paraméterei könnyedén felderíthetőek.
  • a DLL-ek is .NET-ben kerültek leprogramozásra, vagyis egyrészt szintén managelt kódnak minősülnek (pl. a Garbage Collector felügyelet alá esnek), másrészt teljesen lényegtelen, milyen alapnyelven készültek, mivel biztosan meg kell feleljenek az Common Language Specification-nak (CLS). Ennek megfelelően tetszőleges más .NET-es nyelven készülő projektben is gond nélkül beilleszthetőek.

A .NET-es DLL-eket ennek megfelelően már nem is dll-eknek hívják, hanem szerelvényeknek ('assembly') megkülönböztetésül a hagyományos (natív) Win32-es DLL-ekkel szemben. Ugyanakkor a lefordított file-ok kiterjesztése továbbra is '.dll'.

.NET DLL készítése

Amikor DLL-t készítünk, a project típusát Class Library-t kell választani a project típusaként:

Kép:kep.Project_CLASS_LIBRARY.jpg


A Visual Studio által felajánlott kód nem tartalmaz 'Main()' függvényt, mivel ilyet a DLL jellemzően nem tartalmaz. Lehetőségünk van a szokásos módon kódolni, valamely névtérben osztályokat készíteni, azokba a szokásos módon metódusokat, property-ket, mezőket, konstruktorokat készíteni.

Kép:kep.DLL_Forraskod.jpg

Javasolt a kódba dokumentációt is beszúrni. A dokumentációs megjegyzések nem '//' perjel, hanem '///' perjelek mögé vanak rejtve. Amikor valamely mező, metódus, property elé ilyen három perjelet írunk, a Visual Studio automatikusan '<summary>', és hasonló elemeket jelenít meg. Ez 'XML' stílusú kommentezés. A fenti példában látható, hogy lehetővé válik a metódus feladatának leírása ('<summary>' és '</summary>' között), a metódus paramétereinek jelentésének leírása ('<param name="a">' és '</param>' között), valamint a metódus visszatérési értékének leírására ('<returns>' és '</returns>' között).

Ha ily módon felkommentezzük a DLL kódját, akkor ezen dokumentáció nem a lefordított DLL kódjába kerül be, hanem külön dokumentációs file-ba. Ennek nevét és helyét, a project beállításoknál lehet megadni (jobb egérgombos lebegőmenü):

Kép:kep.DLL_ProjectProperties.jpg

Ki kell pipálni a BUILD beállításoknál az 'XML Documentation file' lehetőséget, és ha szükséges, módosítani a felajánlott mentési könyvtárat és filenevet:

Kép:kep.DLL_XMLDoc.jpg

A megadott XML file-ba kerülnek a forráskódból kiemelt dokumentációs kommentek. Ez a DLL-t felhasználó programozó számára igen hasznos lesz később.

.NET DLL belsejében a public class

Amikor DLL-t készítünk, osztálygyűjteményt készítünk. A DLL-ek osztályokból állnak. Ezek közül van olyan osztály, amelyet külső felhasználásra szánunk (ők alkotják a DLL lényegét), de lehetnek olyan osztályok is, amelyek mintegy segédosztályként szolgálnak, és nem kívánjuk őket a DLL-t felhasználó programozó számára elérhetőnek deklarálni.

A DLL-ből a külvilág (felhasználó kód) felé publikus osztályokat meg kell jelölni a 'public' jelzővel. Amelyek segédosztályként szolgálnak, azokat pedig nem kell ezzel megjelölni (az alapértelmezett módosító itt is a 'private'). Az ilyen osztályokat a DLL-t felhasználó kód nem "látja", és nem tudja felhasználni semmilyen formában. Természetesen minden DLL-ben legalább egy publikus osztálynak lennie kell, hiszen ennek hiányában a DLL tartalma a külvilág szempontjából "üres" lenne.

public class FontosOsztaly
{
  ...
}
 
class segedOsztaly
{
  ...
}

Amennyiben publikus osztályt készítünk, néhány szabályt figyelembe kell venni:

  • a publikus osztály ősosztályának is publikusnak kell lennie! Erre akkor kell különösen ügyelni, ha az ősosztály is ugyanebben a DLL-ben található
  • a publikus osztály publikus részeinek típusai is publikusak kell legyenek. Pl. a függvények visszatérési érték-típusa, paramétereinek típusai, property-k típusai, stb.

.NET DLL belsejében internal védelmi szint

Nemcsak az osztályok készítésénél kell figyelni a védelmi szintekre, az osztály belsejében lévő elemekre (property, metódus, mező, stb.) is van kiegészítő szabály. A fenti elemekre egy 'internal' (belső) kiegészítő védelmi szint módosító csatolható. Az 'internal' elemek a DLL belsejére nézve 'public'-ként viselkednek, de a DLL-en kívüli kódra nincs hatással.

Ennek megfelelően az alábbi kombinációk képezhetőek védelmi szintre:

  • 'private', 'protected', 'public': ezek a szokásos viselkedésüek, egyaránt vonatkoznak a DLL-en belülre és kívülre, egyformán értendők mindkét terület felé
  • 'internal private': ez azt jelöli, hogy ez az elem a DLL belsejében 'public'-ként viselkedik, a DLL-n kivülre azonban nem terjed a határköre, így nem elérhető
  • 'internal protected': az azt jelöli, hogy az elem a DLL belsejében 'public', kifelé 'protected'.

Vegyük észre, hogy 'internal public' nincs, mivel ez azt jelentené, hogy a DLL belsejében, és kifelé is 'public'-ként kell az elemnek viselkednie, de ezt a viselkedést az egyszerű 'public' is tudja produkálni, az 'internal' nélkül is.

.NET DLL felhasználása

Amikor valamely projectünkbe egy .NET DLL-t (és nem Win32 DLL-t!!!) kívánunk felhasználni, első lépésként hozzá kell azt adni a projectünkhöz. Ezt megtehetjük a 'Solution Explorer'-en, a 'References' részen. Jobb egérgombbal felbukkanó lebegőmenüben az 'Add reference' menüpontot kell választani:

Kép:kep.DLL_AddReference.jpg

Ennek hatására egy párbeszédablak bukkan elő, amelyben kiválaszthatjuk a projektünkhöz hozzáadható DLL-t. Ennek több módja is van, attól függően, milyen jellegű DLL-t kívánunk hozzáadni:

Kép:kep.DLL_AddRefDialog.jpg

Az első fülön kapjuk meg a.NET rendszerrel szállított DLL-eket. Ezek között szerepelnek a 'Base Class Library'-t alkotó DLL-ek is. Ezek nevei jellemzően 'System.*.DLL'. Mellettük mindig szerepel a DLL verziószáma is.

A 'COM' fülön szerepelnek a .NET elődjének is tekinthető COM (Component Object Model) technológiát használó DLL-ek, amelyek fel vannak telepítve és be vannak regisztrálva a számítógépünkön. Ezek használata .NET-ben lehetséges, de több probléma is van velük kapcsolatosan, az egyik legfontosabb, hogy ha programunkat másik számítógépen is futtatni szeretnénk, nem garantált, hogy azon is fel lesz majd installálva ez a DLL.

A 'Project' fülön a saját 'solution'-ben szereplő 'Class Library' jellegű projectjeink szerepelnek. Innen könnyedén hozzá tudunk adni saját DLL-t.

A 'Browse' fülön a szokásos tallózási lehetőséggel megkereshetünk a háttértárolóról bármely DLL-t, és hozzáadhatjuk azt a projecthez.

A sikeres hozzáadást követően a DLL rákerül a 'References' listára, amelyet kinyitva tájékozódhatunk arról, a futtatható file-unk milyen külső DLL-ektől függ. Amennyiben jobb egérgombbal rákattintunk egy ilyen DLL-re a listán, a lebegőmenüben kiválaszthatjuk a 'View in Object Browser' lehetőséget:

Kép:kep.DLL_ReferecesLista.jpg

Az 'Object Browser' egy objektum-tallózó. Felnyitja a megadott DLL-t, így lehetőségünk van megtekinteni, milyen névterekből áll, melyik névtérben milyen objektum-osztályok találhatóak, azok milyen részekből (mezők, metódusok, property-k) áll. Egy metódusra kattintva kiíródik annak paraméterezése, és visszatérési értékének típusa is:

Kép:kep.DLL_ObjectBowser.jpg

Mint látszik, amennyiben a DLL-ket készítettünk dokumentációs XML file-t is, úgy annak tartalma automatikusan feldolgozásra kerül. De nem csak itt lehetünk ennek tanújele, hanem a kód írásakor az editor ablakban is:

Kép:kep.DLL_inCode.jpg

Amennyiben egy DLL-hez utólag kapcsoljuk be az XML dokumentációs file készítését, elképzelhető, hogy azon projektekben, amelyekben ezt a DLL-t előtte adtuk hozzá - el kell távolítani a DLL file-t a referencia-listáról, és újból hozzáadni, hogy a Visual Studio is érzékelje ezt a változást.

Hernyák Zoltán
A lap eredeti címe: „http://wiki.ektf.hu/wiki/Mp3/ea22
Nézetek
nincs sb_18.222.67.251 cikk