Knihovna (programování)Knihovna (anglicky library) je v informatice označení pro souhrn procedur a funkcí, často také konstant a datových typů (v objektovém programování též tříd, objektů a zdrojů), který může být využíván více počítačovými programy. Knihovny usnadňují programátorovi tvorbu aplikací tím, že umožňují využití hotového kódu, použití jednou vytvořeného kódu v jiných programech; při týmové práci mohou sloužit k dělbě práce. Knihovna poskytuje své služby navenek pomocí API (aplikační rozhraní), které zahrnuje názvy funkcí, předávané parametry a návratové hodnoty. Podle způsobu spojení s programem, který je používá, lze knihovny rozdělit na statické a dynamické. Z hlediska práce s kódem knihovny v operační paměti je dělíme na sdílené a nesdílené. HistorieNejstarší programové koncepty obdobné knihovnám byly vyvinuty, aby oddělily definici dat od realizace programu. Kolem roku 1959 jazyk JOVIAL zpopularizoval koncept COMPOOL (Communication Pool). „Záměrem konceptu COMPOOL bylo povolení sdílení systémových dat mezi více programy pomocí centralizovaného popisu dat.“[1] V roce 1959 byly do jazyka COBOL zahrnuty „primitivní funkce knihovního systému“,[2] které Jean Sammet ve zpětném pohledu popsal jako „nedostatečná knihovní zařízení“.[3] Další významné přispění k modernímu pojetí knihovny přišlo v podobě podprogramu, který byl součástí inovace jazyka FORTRAN. Podprogramy mohou být v jazyce FORTRAN kompilovány nezávisle na sobě, ale kompilátoru chybí linker. Takže před zavedením modulů v jazyce Fortran-90 nebyla mezi podprogramy možná typová kontrola.[4] S významným konceptem přišla též Simula 67. Simula byl první objektově orientovaný programovací jazyk a jeho třídy jsou téměř totožné s moderním pojetím, které je používáno v jazyce Java, C++ nebo C#. Třídy konceptu Simula byly také předchůdcem balíčku v programovacím jazyku Ada a modulu v Modula-2.[5] Třídy Simula mohly být zahrnuty v knihovních souborech a přidány v době kompilace, přestože byly vyvinuty už v roce 1965.[6] Typy knihovenKnihovna je soubor, který obsahuje soubor funkcí a procedur v podobě strojového kódu, které jsou uloženy do společného souboru. Je tak vytvořen archiv, který je souhrnem objektových kódů a se kterým lze dále pracovat. Z technického hlediska je možné rozdělit knihovny podle způsobu propojení s programem, který je bude využívat:
Druhé možné rozdělení je z hlediska možnosti sdílení kódu knihovny mezi více běžícími programy (tj. procesy):
Statické knihovny Podrobnější informace naleznete v článku Statická knihovna.
Statická knihovna tvoří s přeloženým programem kompaktní celek. V závěrečné fázi překladu programu ze zdrojového kódu do strojového kódu jsou volané funkce (a další jimi kaskádově volané funkce) připojovány linkerem (odtud označení linkování) do výsledného spustitelného souboru. V horším případě je k programu připojena celá knihovna bez ohledu na to, jaké části program skutečně využívá. Výsledný spustitelný soubor tak v sobě obsahuje všechny části, které jsou nutné pro jeho běh. Staticky slinkovaný spustitelný soubor proto typicky při spuštění nepotřebuje žádné další soubory, takže je ho možné překopírovat na jiný systém a jednoduše spustit (tj. bez instalace, tak, jak je známá například pro běžné programy v Microsoft Windows). Typickou příponou souboru statické knihovny je Dynamické knihovny Podrobnější informace naleznete v článku Dynamický linker.
Dynamické knihovny nejsou (na rozdíl od statických knihoven) k výslednému spustitelnému souboru přidávány. V závěrečné fázi překladu programu ze zdrojového kódu do strojového kódu jsou odkazy na volané knihovní funkce pomocí linkeru (odtud označení linkování) zapsány do speciální tabulky symbolů, která je připojena k výslednému spustitelnému souboru. Pro chod programu (tj. spuštění výsledného spustitelného souboru) je pak nutné mít k dispozici též příslušné dynamické knihovny. Pokud dynamická knihovna využívá ke své činnosti jiné dynamické knihovny, vzniká řetězec závislostí a všechny potřebné knihovny musí být při spuštění programu přítomny. V Microsoft Windows mají dynamické knihovny příponu Zavaděč Podrobnější informace naleznete v článku Zavaděč (program).
Pro propojení dynamicky linkovaného programu a dynamických knihoven je při spuštění programu používán speciální zavaděč (anglicky dynamic loader). Do operační paměti je zaveden kód vlastního programu (spustitelný soubor) a též kód potřebných dynamických knihoven podle odkazů z připravené tabulky symbolů. Po rozmístění knihoven do operační paměti jsou vyčísleny odkazy z tabulky symbolů podle skutečného umístění jednotlivých částí kódu knihoven v operační paměti, čímž dojde k propojení kódu z dynamicky linkovaného spustitelného souboru s kódem dynamických knihoven. Relokace Podrobnější informace naleznete v článku Relokace.
Knihovny jsou typicky předem připraveny tak, aby mohly být umístěny na konkrétní místo v paměti. Pokud je toto místo již obsazeno (např. jinou knihovnou), musí být provedena relokace na volné místo, která opraví příslušné absolutní adresy použité ve strojovém kódu (v Linuxu mohou být optimální umístění knihoven předem připravena programem prelink, v Microsoft Windows není podobný nástroj volně k dispozici). Dynamic loading Podrobnější informace naleznete v článku Dynamic loading.
Většina dnešních operačních systémů umožňuje načítat dynamické knihovny do paměti až za běhu programu, což umožňuje programy modularizovat a spouštět i v případě že při spuštění programu nejsou k dispozici všechny knihovny, které program používá (takže bude například jen omezena funkčnost programu). Toho se dá využít například k implementaci plug-inů. Sdílené knihovnyKód sdílených knihoven je možné sdílet mezi více programy, čímž jsou efektivně snižovány nároky na velikost potřebné operační paměti. V takovém případě se úsek paměti s kódem knihovních funkcí nalézá ve sdílené paměti, která je přístupná více procesům (je namapována do adresních prostorů všech procesů, které ji používají). Protože knihovny typicky pracují se svými interními daty, musí být možné zajistit každé knihovně privátní datový prostor pro data pro každý proces zvlášť. Přitom se s výhodou využívají možnosti virtuální paměti, jejíž podpora musí však být přítomna v procesoru. Sdílet je možné jen identické knihovny. Z technického hlediska možné sdílet jen dynamické knihovny, protože jen u nich je zaručeno, že se vždy jedná o naprosto stejný kód (z principu není možné při startu programu porovnávat kód statický linkované knihovny s obsahem paměti ostatních spuštěných procesů). Nastavení sdílení paměťového prostoru se kódem sdílených dynamických knihoven zajišťuje při startu dynamicky linkovaného programu výše zmíněný dynamický zavaděč (anglicky dynamic loader). Podpora v operačních systémechPrincip sdílených dynamických knihoven je propracován zejména v unixových systémech, kde již v dobách jeho vzniku umožňoval efektivní využití drahé a poměrně malé operační paměti (v 70. a 80. letech 20. století byla operační paměť tehdejších sálových počítačů veliká pouze desítky kilobajtů). V systémech Microsoft Windows je sdílení DLL knihoven omezeno a od Windows Vista firma Microsoft doporučuje, aby každý program měl vlastní dynamické knihovny, protože ve Windows neexistuje centrální správa sdílených knihoven na úrovni systému. Tím je jejich sdílení v paměti fakticky znemožněno (i přesto, že mohou být některé identické) a proto prudce eskalovaly nároky na minimální velikost operační paměti. Již od počátku návrhu DLL knihoven nebylo maximální sdílení stejné knihovny různými procesy prioritním cílem, protože se nepředpokládalo, že na tehdejším dostupném hardware bude možné spouštět desítky až stovky programů současně (tím také byly sníženy paměťové nároky jdoucí na vrub možnosti sdílení knihovny mezi více procesy) a zároveň procesor Intel 8086 neposkytoval podporu virtuální paměti. Knihovny DLL se proto soustředily na maximalizaci úspory paměťového prostoru a na vytvoření společného paměťového prostoru knihoven a programu. Správa sdílených knihovenPokud mají být dynamické knihovny sdíleny více spuštěnými programy (tj. více procesy), musí všechny tyto programy využít naprosto stejnou dynamickou knihovnu. Toho lze dosáhnout jedině tak, že všechny programy jako knihovnu použijí stejný soubor. Knihovny jsou proto soustředěny na centrální místo. V unixových systémech jsou to zejména základní adresáře Protože i knihovny obsahují chyby, jsou vydávány novější verze a navzájem jsou odlišeny čísly. Číslo je typicky uvedeno uvnitř knihovny. Někdy jsou změny v novější verzi knihovny větší a v systému je vhodné mít kromě starší verze knihovny pro dříve přeložené programy (resp. pro programy linkované proti starší knihovně) zároveň i novější verzi knihovny pro novější verze programů. Aby mohly být různé verze knihoven umístěny ve stejném adresáři, jsou v jejich názvu uvedena čísla verze (nemusí být nutně stejné, jako jsou dříve zmíněná čísla uvedená uvnitř knihoven). V názvech se typicky používají tři čísla: major, minor a patchlevel (hlavní číslo generace pro velké změny v rozhraní knihovny, vedlejší číslo pro odlišení kompatibility a poslední číslo označuje opravu chyb se zachováním kompatibility). Pro zajištění pořádku v různých verzích knihoven a usnadnění nalezení nejvýhodnější verze je unixových systémech nástroj ldconfig, který projde všechny adresáře s knihovnami a vytvoří databázi všech dynamických knihoven do souboru Nejdůležitějším rysem správy dynamických sdílených knihoven je jejich údržba, kdy tvůrce systému musí vydávat opravené verze knihoven a zajišťovat, že nedojde ke ztrátě kompatibility (nebo je nekompatibilní knihovna označena jiným číslem verze). Tuto správu běžně dělají tvůrci linuxových distribucí. Naproti tomu firma Microsoft pro své systémy Microsoft Windows nikdy takovou údržbu nedělala. Dynamické knihovny (soubory DLL) nemají v názvu číslo verze, a proto novější verze knihovny přepíše starší verzi. Pokud je novější verze nekompatibilní (číslo verze je uvnitř DLL souboru), mají starší programy jiných tvůrců problém (Microsoft si kompatibilitu v rámci svých produktů může snadno zajistit). Tomuto neorganizovanému a nepředvídatelnému stavu se říká DLL hell (DLL peklo). Proto je v novějších systémech Windows doporučeno, aby každý program měl vlastní soubory s knihovnami, což však brání sdílení kódu knihoven v paměti pro více procesů. Tímto opatřením se samozřejmě snižují náklady na údržbu systému na straně tvůrce systému, ale ztěžuje se použití knihoven programátorům aplikací a zvyšují se nároky na velikost nutné operační paměti RAM (tj. přenáší se náklady na uživatele počítačů, protože knihovny se v paměti nesdílí, pro které je potřeba mnohem více operační paměti). Srovnání statické a dynamické knihovny
Návrh knihovnySoučástí návrhu většího softwarového projektu je obvykle i oddělení části funkčnosti do jedné nebo několika samostatných knihoven. Při návrhu knihovny se berou v úvahu především některé vlastnosti známé (na nižší úrovni) z objektově orientovaného programování:
Dynamické knihovny v platformě Linux/UnixDynamické knihovny jsou v platformě Linux a Unix označované jako sdílené objekty. Sdílený objekt (angl. Shared object), také označován jako je soubor, který je určen ke sdílení spustitelnými soubory (programy) nebo jinými sdílenými objekty. Jedná se o unixovou/Linuxovou obdobu DLL knihoven z operačního systému Windows. Z toto objektu jsou při startu programu nebo během jeho chodu načítány do paměti systému jednotlivé rutiny knihovny, které jsou využívány za běhu programu. Díky tomu nemusí linker při kompilaci programu tyto metody zakomponovávat přímo do programů a vytvářet tak ohromné monolitické programy.
Většina moderních operačních systémů může mít soubory sdílené knihovny ve stejném formátu jako spustitelné soubory. To nabízí dvě hlavní výhody. za prvé, místo dvou loaderů pro každý typ zvlášť stačí jen jeden loader pro oba. Za druhé, umožňuje spustitelné také použít jako knihovny, pokud mají tabulku symbolů. Typické kombinace spustitelný soubor a knihovny jsou formáty ELF a Mach-O (oba Unix) a PE (Windows). Vytvoření SO pomocí GCCPostup vytvoření sdílené knihovny probíhá v několika krocích. Následující příklad objasňuje symbolicky celý postup. Zdrojový kód knihovny je uložen v souborech $ gcc -fPIC -g -c -Wall prvni.c
$ gcc -fPIC -g -c -Wall druhy.c
$ gcc -shared -Wl,-soname,libMyMethods.so.1 -o libMyMethods.so.1.0.1 prvni.o druhy.o
První dva příkazy přeloží díky přepínači Poslední příkaz vytvoří vlastní knihovnu (přepínačem Příklady různých knihoven
Reference
Externí odkazy
|
Portal di Ensiklopedia Dunia