Jazyk, díky němuž se objekty domluví

V letošním 15. čísle Computerworldu jsme se v TECH-Tipu nazvaném "Řešení pro vzájemnou spolupráci distribuovaných a...


V letošním 15. čísle Computerworldu jsme se v TECH-Tipu nazvaném "Řešení pro
vzájemnou spolupráci distribuovaných aplikací" věnovali standardu CORBA a mj.
jsme zmínili i pojem IDL. Dnes se na IDL, deklarativní jazyk pro definování
rozhraní CORBA objektů, podíváme podrobněji.
Připomeňme si nejdříve, co IDL vlastně je. Jedná se o jazykově nezávislý
způsob, který implementátorovi a uživateli objektu zajišťuje bezpečné volání
objektů. IDL překladače generují kó-dy stubů a skeletonů (viz vložený slovník
pojmů).
Syntaxe jazyka vychází z C++, ale obsahuje odlišná klíčová slova. Nejsou zde
žádné výkonné příkazy, protože úkolem je definovat popis rozhraní datový typ
návratové hodnoty metody, datové typy jednotlivých parametrů a jejich druh,
způsob volání metody, její kontext a možné výjimky, které může generovat. Pro
tento účel jsou dostatečné následující konstrukce:
konstanty používají se při deklaraci typů
deklarace typů požívají se pro typování parametrů
atributy obsahují hodnoty určitého typu
operace přebírají parametry a vrací hodnoty
interface sdružují datové typy, atributy a deklarace operací
moduly oddělují prostory jmen
Všechny deklarace provedené v IDL jsou dostupné skrze Interface Repository
(IR), což je jedna ze standardních součástí architektury CORBA.
Klíčová slova
Gramatika IDL obsahuje např. následující klíčová slova: any, double, interface,
readonly nebo unsigned, která musí být zapsána přesně tak, jak jsou uvedena.
Zápis boolean je správný, ale Boolean způsobí chybu, jazyk IDL je tedy citlivý
na velikost písmen. Klíčové slovo Object může být použito jako specifikátor
typu.
V jazykových konstrukcích můžeme používat i speciální znaky především středník,
závor-ky, matematická znaménka apod. Pro komentář platí stejná pravidla jako v
jazyce C++.
Identifikátor musí začínat písmenem, za kterým může následovat libovolně dlouhá
posloupnost písmen, číslic a podtržení. Je zde určitá nelogičnost, protože
překladač testuje ve jménech identifikátorů, zda jsou správně zapsána malá a
velká písmena, ale přitom nemohou existovat dva identifikátory, které se liší
pouze velikostí písmen. Důvodem tohoto zdánlivě podivného chování je, že při
mapování do jazyků, které nerozlišují malá a velká písmena, by překladač nebyl
schopen správně vyřešit patřičné odkazy.
Moduly a rozhraní
Úkolem IDL je definovat interface a jeho operace. Abychom se při definování
vyhnuli nejednoznačnostem použitých jmen, používá se v IDL souborech konstrukce
modul, která definuje rozsah (prostor) platnosti jmen. Modul může obsahovat
vnořený modul. Také interface otevírá nový rozsah platnosti jmen a může
obsahovat konstanty, deklaraci datových typů, atributy a operace.
// priklad: RezervacniProstor.idl
{module RezervacniProstor
{}interface Prostor ;
};
Libovolné jméno interface se může použít jako jméno typu. Pokud není interface
ze stejného rozsahu platnosti, musíme použít jeho úplné jméno např.
RezervacniProstor::Prostor. Můžeme též použít
zápis ::RezervacniProstor::Prostor, abychom explicitně vyjádřili jeho vztah ke
globálnímu prostoru jmen.
Moduly mohou být vnořovány a pak můžeme použít pojmenování relativní k
aktuálnímu prostoru jmen.
Interface mohou vzájemně odkazovat jeden na druhý. Abychom se vyhnuli chybám
při překladu, je možné použít tzv. předčasnou nebo neúplnou (forward) deklaraci:
interface A;
// předčasná deklarace
B může použít předčasně deklanovaný interface jako jméno typu
{interface B
get_A();
};
interface A}
get_B();
};
Neúplné deklarace se často používají spíše z důvodu čitelnosti než vzájemné
závislosti. Pokud deklarace v modulu vyžaduje odkaz na deklaraci v jiném
modulu, provedeme to nejčastěji tak, že uzavřeme první modul a opětovně ho
otevřeme po jiných deklaracích.
Datové typy
Jméno libovolného interface se stává jménem objektového typu, který můžeme
použít jako typ parametru ve funkci nebo jako typ návratové hodnoty nebo jako
položku ve strukturovaném datovém typu. Základní datové typy jsou podobné jako
v jazyce C.
Klíčové slovo typedef umožňuje vytvářet synonyma pro libovolné legálně
deklarované datové typy. V případě typových šablon(typů, u nichž je vyžadován
parametr pro určení délky nebo obsahu) se požaduje vytvoření synonyma před
použitím typu v deklaraci.
Výčtové typy jsou deklarovány se jmény, která mohou být použita jako platné
datové typy, a seznamem identifikátorů oddělených od sebe čárkami, např:
enum technology digital, analog;
V jazyce IDL lze používat také uniony, posloupnosti (typové šablony) a pole,
výjimky nebo konstanty.
Dědičnost
Funkčnost jednoho interface může být rozšířena deklarováním nového interface,
který je jeho dědicem. Původní interface se nazývá základní a nový se nazývá
odvozený. Dědičnost je deklarována pomocí dvojtečky po jméně nového iterface, a
za ním následuje jméno základního interface. Vše je vidět na následujícím
příkladu:
module PrikladDedicnosti{
interface A{
typedef unsigned short ushort;
ushort op1();
};
interface B:A{
boolean op2(ushort num);
};
};
Interface B rozšiřuje interface A a nabízí operace op1 (tu zdědil) a op2.
Deklarace datového typu je také zděděna, takže typ ushort může být použit jako
typ parametru.
Interface může dědit od několika interface. Syntax je podobná jako u jednoduché
dědičnosti, základní interface jsou od sebe odděleny čárkami.
Jména operací a atributů v každém z děděných interface (včetně operací
zděděných z ostatních interface) musí být jedinečná a nesmí být v odvozeném
interfaceu předeklarována. Výjimkou z tohoto pravidla je situace, kdy se
operace dědí ze dvou nebo více tříd se společnou základní třídou. To je známo
jako čtvercová závislost(diamond inheritance), kdy graf dědičnosti tvoří
čtverec.
Operace a atributy
Deklarace operací jsou podobné prototypům funkcí v C++. Obsahují jméno operace,
návratový typ, seznam parametrů(může být prázdný). Navíc zde může být klauzule
raise, která specifikuje, jaké uživatelské výjimky může operace vygenerovat.
Dále může být uvedena klauzule context specifikující prostředí, v němž bude
operace vykonávána.
Seznam parametrů je uzavřen v závorkách a jednotlivé parametry jsou od sebe
odděleny čárkou. Každý parametr musí mít specifikován směr, kterým se přenáší
data:
indata z klienta do objektu
outdata z objektu do klienta
inoutdata jdou z klienta do objektu a zpět
Operace může být deklarována jako oneway. Volající může ihned pokračovat a
nečeká na dokončení operace. Volaná operace musí mít návratový typ void, nesmí
obsahovat žádné parametry typu out nebo inout a nesmí házet žádné výjimky.
U operací vykonávaných způsobem oneway může za určitých podmínek docházet k
problémům (deadlocku), které lze řešit např. vícevláknovým zpracováním
(multithreading) nebo spojením časovače s každým voláním metody. Pokud časové
kvantum vyprší dříve, než se provede návrat z metody, metoda vyhodí výjimku.
Tento mechanismus nám sice umožní zotavit se z deadlocku, ale neochrání nás
před jeho výskytem. Další možností je použití neblokujícího volání oneway.
Pseudo-IDL objekty
Interface ke komponentám ORBu jsou specifikovány v IDL. To poskytuje jazykově
neutrální reprezentaci rozhraní ORBu. Avšak některé části těchto definic jsou
označeny jako pseudo-IDL (PIDL), což znamená, že jejich implementace nejsou
nezbytně CORBA objekty. To obvykle znamená, že to je knihovna, která je
přilinkována k aplikaci, která ji používá. Ačkoli jsou operace na
pseudoobjektech vyvolávány stejným způsobem jako na skutečných CORBA objektech,
odkazy na tyto objekty nelze předávat jako parametry skutečným CORBA objektům.
Primární pseudoobjekty jsou BOA(Basic Object Adapter), Context, Environment,
NVList, ORB, Request, Principal a TypeCode.
Závěr
Problematika IDL je pochopitelně daleko obsáhlejší a vydala by nikoli na jeden
článek, ale na několik knih. Přesto doufáme, že se nám podařilo alespoň
naznačit možnosti a způsob použití tohoto jazyka.
Slovník pojmů
Proxy je zástupný objekt, který reprezentuje skutečný objekt ležící mimo dosah
aktuálního objektu (obvykle v jiném adresovém prostoru, na jiném počítači
apod.).
Stub je část programu zodpovědná za překlad volání proxy na zprávu pro skeleton.
Skeleton je část programu zodpovědná za překlad zprávy od stubu na volání
zastupovaného objektu. Tyto kódy konvertují paměťové datové struktury jednoho
programovacího jazyka do síťového streamu a na druhém počítači je rozbalí do
ekvivalentní datové struktury jiného programovacího jazyka, vyvolají metodu a
výsledek předají zpět.
9 2144 / pen









Komentáře
K tomuto článku není připojena žádná diskuze, nebo byla zakázána.