karel_pavlovsky_predavani_parametru
Transkript
karel_pavlovsky_predavani_parametru
Předávání parametrů Common Česká republika 2008-05-20 Předávání parametrů Common Česká republika 2008-05-20 (všechny příklady, které tento materiál obsahuje byly vytvořeny pod OS/400 verze 5.4, DHL produkce KPLIB QCLSRC, QRPGLESRC) Karel Pavlovský, DHL, 20.5.2008 Obsah Úvod Předávání parametrů při volání programů z povelové řádky Předávání parametrů při použití povelu (*CMD) Jednoduché proměnné Seznamy hodnot Proměnná délka Předávání parametrů při volání programů a procedur mezi sebou Předávání referencí. Předávání referencí read-only. Předávání hodnotou Jednotlivé možnosti předávání v jazyku CL Povel CALL Povel CALLPRC Jednotlivé možnosti předávání parametrů v jazyku RPG Prototypové volání Prototypové volání předávání parametrů Použití Operačního popisu Vynechávání parametrů Kontrola počtu parametrů Předávání menší porce dat než je požadováno Pořadí, ve kterém se vyhodnocují hodnoty parametrů ve volaném programu Okolnosti, nastávající při předávání parametrů mezi různými programovacími jazyky. Neprototypové volání Seznam použitých zdrojů 1 / 24 Předávání parametrů Common Česká republika 2008-05-20 Úvod Většina programů, se kterými se v praxi setkáme používá parametry. Oproti těm, které pracují bez parametrů, jsou tyto programy pružnější, přinášejí možnost různých variant zpracování. Větší pracnost při tvorbě takových programů je vyvážena veěší univerzálností jejich nasazení. Procesu předávání se vždy zůčastňují dvě strany, ta která něco předává, a ta která něco příjimá. Vlasní předání může dobře proběhnout jen tehdy, pokud přijímající strana je na příjem dobře připravená. A připravit se může tehdy, pokud má dostatek informací o tom, co bude přijímat. Tohle obecné pravidlo platí i při předávání parametrů. Pro předávání a příjem parametrů je na straně předání i příjmu vytvořen tak zvaný "calling interface". Ten se může lišit podle toho o jaké volání se jedná , co se volá a jaký programovací jazyk se používá. Při volbě calling interface přichází do úvahy následující skutečnosti: • Kontrola parametrů v době překladu programu. Pokud je k dispozici, může vyloučit pozdější havarie programu způsobené nekompatibilitou na staně volání a příjmu. • Volba metody předávání. V řadě případů je možno volit mezi několika metodami, které se co možností, bezpečnosti ale i rychlosti liší. Jedná se o volbu mezi možností, předat ukazatel, předat kopii parametru a nebo předat samotný parametr. • Předání operačního popisu parametru. Někdy je potřeba vyřešit situaci, kdy se charakteristiky předávané hodnoty případ od případu liší a je možno je zjišťovat až v okamžiku volání. Právě na to je možno využít operační popis parametru. • Proměnný počet předávaných parametrů. To je další aspekt, který je možno některými metodami calling interface vyřešit. • Případ kdy se liší charakteristiky parametru na straně volání a příjmu. • Pořadí, ve kterém se vyhodnocují hodnoty parametrů ve volaném programu. • Okolnosti, nastávající při předávání parametrů mezi různými programovacími jazyky. V následujícím materiálu se budeme zabývat řadou případů předávání parametrů, které v prostředí iSeries OS/400 nastávají. Předávání parametrů při volání programů z povelové řádky Na povelové řádce jsou pro volání programů k dispozici CL povely CALL a TFRCTL. Oba povely mají jeko jeden z parametrů parametr PARM. U obou ale chybí jakýkoliv popis toho co se předává a kde bude předávaná hodnota umístěna. V obou případech jsou proto předem stanovana pravidla jednoznačně určující jak se pozná typ předávaného parametru a kde je parametr umístěn. Povel CALL. 2 / 24 Předávání parametrů Common Česká republika 2008-05-20 Na parametry předávané pomocí povelu CALL se vztahují následující omezení: Parametry mohou být pouze následujících typů • konstanty typu o o o o o znakový řetězec dekalické číslo logická hodnota číslo ve formátu s plovoucí řádovou čárkou CL proměnná. (ta se v našem případě, kdy uvažujeme volání programu z povelové řádky nemůže použít) Na místě parametru se nemůže objevit seznam hodnot, kvalifikovaná proměnná, výraz, prázdná hodnota nebo klíčový parametr. Maximální počet parametrů je 255. Konstanty se na místě parametrů používají bez jakéhokoliv dalšího popisu. Určení o jakou konstantu jde, provede OS/400 na základě způsobu zápisu. Z uvedených formátů se všechny, až na plovoucí řádovou čárku mohou ilustrovat na příkladech vytvořených v jazyku CL. Formát plovoucí řádové čárky jazyk CL nezná a proto ho musíme ilustrovat na programu v RPG IV. Přesnost/rozsah je dána/dán stanovenými pravidly pro jednotlivé typz parametrů: Konstanta - řetězec znaků. Řetězce znaků o délce <= 32 se do volaného programu předávají v délce 32 znaků. Řetězce delší než 32 znaků se předávají ve svojí délce. V případě, že volaný program je připraven na na příjem kratšího řetězce, je řetězec před předáním zprava zkrácen na požadovanou hodnotu. Pokud je řetězec kratší než 32 znaků a proměnná ve volaném programu je delší, OS/400 nedoplní konstantu do požadované délky. Viz příklad KR1 . KR1: Zdrojový kód volání obsah symbolických proměnných po zavolání: 3 / 24 Předávání parametrů Common Česká republika 2008-05-20 Je patrno, že v paramtrech PARM2 a PARM3 jsou na konci znaky, které nebyly do programu předány. volání obsah symbolických proměnných po zavolání Na příkladu KR1 je vidět situace, kdy se do proměnné&parm2 dostanou mimo konstanty dlouhé dvacet znaků ještě další nedefinované znaky. Jedna z možností jak předávat řetězec znaků je použití hexadecimální notace. Konstanta - dekalické číslo. Konstanta ve tvaru dekalické číslice se převede do pakovaného tvaru s přesností 15,5. Na příkladu KD1 je situce dobře ilustrována. KD1 zdrojový kód 4 / 24 Předávání parametrů Common Česká republika 2008-05-20 volání 1 nebo obsah symbolických proměnných po zavolání Je vidět, že jediný případ, kdy je v předané proměnné hodnotě očekávané číslo je PARM1, kdy je parametr definován přesně tak, jak systém očekává! volání 2 call PGM(KPLIB/KD1) PARM( 62 5389 156789) obsah symbolických proměnných po zavolání Konstanta - logická hodnota. 5 / 24 Předávání parametrů Common Česká republika 2008-05-20 Konstanta ve tvaru logické hodnoty by měla být předávána vždy jako logická hodnota '1' nebo '0'. Na příkladu KB1 je vidět způsob přenosu i fakt, že se tímto způsobem se dá do logické proměnné dostat i jiný znak nežli '0' nebo '1'. KB1 volání obsah symbolických proměnných před přesunem po přesunu do &STR po provedení logické operace (????) Konstanta - formát plovoucí řádová čárka Konstanty a speciální hodnoty ve formátu s plovoucí řádovou čárkou jsou předávány s dvojitou přesností 8 bytů v podobě sn.nEsn; kde s je (+) nebo (-) znaménko. Na příklad -2.47E+3 nebo 3.653E24. Předávání konstant v tomto formátu je umožněno pouze v programovacích jazicích, kde se tento formát vyskytuje. V CLLE to není, takže pro uvedení příkladu musíme přejít do jazyku RPG IV. Příklad programu a volání viz KP1. KP1 Zdrojový kód 6 / 24 Předávání parametrů Common Česká republika 2008-05-20 volání obsahy proměnných po zavolání Je vidět, že druhá hodnota se převedla s chybou ! Předávání parametrů při použití povelu (*CMD) Použití povelu (objekt typu *CMD) podstatně rozšiřuje oblast použitých hodnot při předávání parametrů. Z povelu se parametry předávají do CPP programu (program, který přebírá parametry a realizuje funkci povelu), ale na rozdíl od přímého předávání z povelové řádky při použití povelu CALL jsou možnosti definování parametrů umožněné vytvořením povelu podstatně bohatší. Jazyk pro vytváření povelů umožňuje definovat celou řadu různých typů parametrů. Jejich hodnoty, mohou být nejrůznějším způsobem kontrolovány a provázány mezi sebou. V tomto příspěvku se stručně zmíníme o třech druzích parametrů, které se v povelech mohou používat. Jsou to jednak parametry obsahující jednoduchou hodnotu, parametry obsahující hodnoty s proměnnou délkou a parametry obdahující seznamy hodnot. Jednoduché proměnné Pro uživatelské povely může být typ předávaného parametru: *DEC Do CPP programu je předávána pakovaná hodnota udaného dekalického čísla v délce a přesnoti udané v parametru LEN. Pokud zadaná hodnota obsahuje víc pozic za desetinou čárkou, nežli je udáno v LEN parametru, je délka zkrácena podle definice. *LGL. Parametrem může být logická hodnota ’1’ nebo ’0’. Ta se předává do proměnné CPP programu jako řetězec o délce jednoho bytu shonotou X'F1' nebo X'F0'. 7 / 24 Předávání parametrů Common Česká republika 2008-05-20 *CHAR Parametrem je řetězec znaků, který může být uzavřen do jenoduchých apostrofů od délce zadané parametrem LEN. Při předáváví do proměnné v CPP programu jsou apostrofy odstraněny, řetězec je zarovnán doleva a eventuelně, je-li kratší nežli je délka přijímající proměnné, doplněn zprava blanky. *NAME Specielní typ řetězce, který splňuje požadavky kladené na jméno. Jeho maximální délka je 256 znaků, prvním znakem mohou být znaky abecedy A-Z nebo některý ze znaků $, #, or @. Ostatní znaky řetězce mohou mimo to být i číslice 0 - 9 nebo znaky podtržítko (_), nebo tečka (.). Další možností je řetězec znaků uzavřený do úvozove (″). Systém předává hodnotu do proměnné jako řetězec znaků v délce LEN. Řetězec je zarovnán doleva a doplněn, pokud to vyžaduje délka přijímající proměnné, zprava mezerami. Tento typ parametru se použá pro předávání jména. Pokud je zapotřebí předat jako jméno nějaké zvláštní jméno, například *LIBL, použije se jiný typ - SPCVAL. *SNAME - Simple Name Na hodnotu předávanou pomocí tohoto typu se vztahují stejné požadavky jako na typ *NAME, na rozdíl od *NAME ale nepovoluje uvnitř jména tečky. *CNAME - Comunication Name Na hodnotu předávanou pomocí tohoto typu se vztahují stejné požadavky jako na typ *NAME, na rozdíl od *NAME ale nepovoluje uvnitř jména podtržítka (_). *PNAME - Path Name Systém předává hodnotu do proměnné jako řetězec znaků v délce LEN. Řetězec je zarovnán doleva a doplněn, pokud to vyžaduje délka přijímající proměnné, zprava mezerami. Path Name je řetězec znaků využívaný k lokalizaci objektů v IFS. Takový řetězec obsahuje obvykle jeden či více řetězců oddělených znakem lomeno(/). Každý z těchto řetězců s vyjímkou posledního zprava je obvykle jménem adresáře. Tam se může použít jedna z následujích možností: jméno adresáře, jméno objektu nebo generické jméno objektu. V některých povelech je dovoleno použít místo znaku lomeno(/) znam zpětné lomítko(\). Path Name musí být representováno v CSSID, které nastavené při běhu jobu. Jeho maximální délka je 5000 znaků. V závislosti na tom, kde v jaké části IFS se objekt nachází se pak mohou vyskytovat například následující názvy" v části QSYS - ’/QSYS.LIB/PAY.LIB/TAX.FILE’ v independent ASP -’/asp-name/QSYS.LIB/PAY.LIB/TAX.FILE’ *GENERIC - Generické jméno Jedná se o název kterým pojmenováváme celou skupinu objektů, jejichž název začíná stejným řetězcem. Toto jméno je zakončeno hvězdičkou (*). Tak například jméno jméno *INV zastupuje všechny objekty ze skupiny INV, INV, INVOICE a INVENTORY. *DATE Typ Datum. Do CPP proměnné se předává řetězec znaků ve formátu cyymmdd (kde c je století, y je rok, m je měsíc a d je den). Pro hodnotu c systém nastavuje hodnotu podle zadaného roku. Pokud jsou ve vstupní hodnotě vyhraženy pro rok čtyři číslice systém přiřadí pro c hodnotu 0 pro roky které začínají 19 a hodnotu 1 pro roky které začínají hodnotou 20. Pokud jsou ve vstupní hodnotě vyhraženy pro rok jen dvě číslice systém přiřadí pro c hodnotu 0 pro roky v intervalu 40 až 99 a hodnotu 1 pro roky z intervalu 40 až 99. Zadání datumu se musí shodovat s hodnotami DATFMT a DATSEP zpracovávaného jobu. Rozsah možných hodnot je pak v závislosti na délce roku: 2 číslice roku – January 1, 1940 až December 31, 2039 4 číslice roku - August 24, 1928 až May 9, 2071. *TIME 8 / 24 Předávání parametrů Common Česká republika 2008-05-20 Typ čas. Do CPP proměnné se předává řetězec znaků ve formátu hhmmss (kde h je hodina, m je minuta a s je vteřina). Hodiny, minuty a vteřiny mohou být podle nastavení TIMSEP jobu odděleny oddělovačem. *HEX Typ hexadecimální hodnota. Řetězec obsahující znaky 0 -F. Řetězec se předává do CPP jako řetězec hexadecimálních znaků v kódu EBCDIC (jeden znak je reprezentován dvěma znaky řetězce). Řetězec je zarovnán doleva a doplněn, pokud to vyžaduje délka přijímající proměnné, zprava nulami. Pokud je řetězec uzavřen do apostrofů musí obsahovat sudý počet znaků. *ZEROELEM Typ nulový element. Tento typ parametru reprezentuje seznam nulových honot(hodnot, které nebyly zadány). Slouží pro případ, kdy je zapotřebí uspokojit CPP program tím že dostane formálně správný seznam hodnot, které jsou ale prázdné. Příklad: Dva povely používají stejný CPP program. První povel umožňuje zadání seznamu parametrů a v případě druhého povelu je zapotřebí zabezpečit, aby nebylo možno seznam zadat. Parametr v druhém případě je pak zadám pomocí TYPE(*ZEROELEM). *INT2 nebo *INT4 Typ celočíselný s rozsahem na dva nebo čtyři byty. V CPP CL programu pro tento typ parametru nachystáme proměnnou typu *INT nebo proměnnou deklarujeme jako *CHAR a zpracujeme jí pomocí vestavěné funkce %BINARY. *NULL Typ NULL je určen pro vyhražení místa pro proměnnou typu pointer. *CMDSTR Parametr obsahuje povel. Jak je patrno z předchozího umožňuje použití konstrukce pro povel (*CMD) další rozšíření při předávání parametrů a to jak při volání povelů z povelové řádky, tak při jejich použití uvnitř programů. Mimo různých zvláštních tyypů řetězců, za které lze považovat typy *NAME, *SNAME, *CNAME, *PNAME, *GENERIC, *HEX a *CMDSTR přibývají možnosti s předáváním data *DATE, času *TIME, proměnných typu integer *INT2 a INT4 a dále zcela speciální parametry jako *ZEROELEM a *NULL. Za nejpodstatnější se ale dá asi považovat nová možnost zadání délky a přesnosti parametru u většiny z nich. Příklad KCMD1 ilustruje jak je možno pomocí povelu vyřešit problém délek řetězců i přesnost dekalického parametru. KCMD1: Zdrojový kód povelu KCMD1 9 / 24 Předávání parametrů Common Česká republika 2008-05-20 Zdrojový kód CPP programu KCMD1 volání Je patrné, že command hlídá délky, přesnosti a hodnoty parametrů podle zadání. Volání po změně hodnot obsah symbolických proměnných po zavolání 10 / 24 Předávání parametrů Common Česká republika 2008-05-20 Seznamy hodnot Další rozšíření možností v oblasti předávání parametrů při použití povelů je možnost předávat seznamy. Seznamy mohou být jednak jednoduché, připomínající jednorozměrná pole POLE(n), kde každý prvek pole má stejné charakteristiky, nebo mixované, připomínající struktury, kde prvky seznamu mohou mít rozličné charakteristiky nebo seznamy seznamů obou typů, které připomínají buď vícerozměrná pole Pole(n m), jsou-li charakteristiky prvků stejné, nebo, jsou-li charakteristiky rozličné pole struktur. Pro specifikaci pole se při definici povelu využívá možnosti zadat hodnotu parametru jako vícenásobnou. Přitom lze pro libovolný parametr rovněž stanovit, že bude setávat z několika hodnot. Využitím těchto dvou možností pak vznikají uvedené seznamy. Při volání se v poli hodnot pro seznamy mohou podle typu definovaného seznamu následující možnosti: jednoduchý seznam mixovaný seznam seznam seznamů, jednoduchý sesznam seznamů mixovaný - PARM1((VAL1 VAR2 VAR3)) PARM1((VAL1 1.0 '0') PARM1((VAL1 VAL2 VAL3) (VAL4 VAL5 VAL6)) PARM1((VAL1 1.0) (VAR2 2.0) (VAR3 3.0)) Definice povelu připouští, aby některé parametry byly definovány jako nepovinné. Proto je při předávání hodnot do CPP programu nezbytné, aby současně s hodnotami, byly k dispozici údaje o tom kolik a kterých parametrů povel předává. Proměnná délka Je další zajímavé rozšíření předávaných hodnot, které použití povelu přináší. Umožňuje předávat parametry proměnné délky. Pouze parametrz typu *CHAR, *NAME, *SNAME, *CNAME, *PNAME, *GENERIC, *LGL, *VARNAME, *CMD, *CMDSTR, and *X umožňují použití proměnné délky. Princip je vždy stejný. Délka parametru je stanovena na určitou maximální hodnotu a skutečná délka obsahu je uložena ve 2 nebo 4 bytech před parametrem. Situace je ilustrována na povelu ZEROSUP a CPP programu ZEROSUP, který zpracovává data. ZEROSUP Zdrojový kód povelu 11 / 24 Předávání parametrů Common Česká republika 2008-05-20 Zdrojový kód CPP program volání obsah symbolických proměnných po zavolání: Definovaná délka vstupního parametru VALUE je 34 bytů a skutečná vložená délka řetězce je 16 bytů. V prvních dvou bytech je ve formátu INT2 uložená délka X¨0010' (16). Předávání parametrů při volání programů a procedur mezi sebou 12 / 24 Předávání parametrů Common Česká republika 2008-05-20 Pro předávání parametrů mezi programy a procedurami jsou k dispozici povely realizující předávání řízení. V CL jazyku jsou to povely CALL, CALLPRC a TFRCTL. V jazyku RPG jsou to povely CALL, CALLB a CALLP. Vesměs se jedná o předání řízení do vstupního bodu. Vstupní bod může být buď hlavní vstupní bod programu(to byla až do příchodu ILE jediná možnost) a nebo některý ze sekundárních vstupních bodů programu realizovaný procedurou obsaženou v programu, procedurou obsaženou v modulu, který je součástí programu a nebo procedurou, která je částí modulu, ze kterého je vytvořen servisní program. Na úrovni jednotlivých povelů v CL a RPG jazycích se mohou používat různé základní metody předávání, dále upřesňované pomocí klíčových slov. Pro správnou funkci programů je v každém případě třeba, aby volaný program, očekávající na základě daných pravidel nějaký parametr, dostal očekávanou hodnotu v očekávaném formátu. Současný stav jazyků CL a RPG umožňuje, díky variantám předávání, volat prakticky všechny systémové procedury(API) včetně těch, které jsou realizovány v jazyku C. Pro předávání parametrů se v OS/400 nabízejí následující možnoti: Předávání referencí. Je to metoda, která se použije, pokud se explicitně nezadá některá z dále uvedených. Pro povel CALL je to jediná možná metoda. Je jednoduchá a nejrychlejší ze všech. Spočívá v tom, že se do volaného programu předá ukazatel na předávanou hodnotu. To má za následek, že se přepis předaného parametru ve volané proceduře projeví také přepisem předávaného parametru. Jakkoliv se to nezdá důležité, vede použití této metody ve složitějších strukturách vhnízděných procedur na těžce odhalitelné chyby. To je důvod proč se doporučuje tuto metodu pokud možno nepoužívat. Pro lepší představu bychom mohli připodobnit tuto metodu situaci, kdy se v knihovně z poličky čtenář vypůjčí knížku a při čtení si do ní dělá poznámky, vytrhuje listy a jinak jí ničí. Pak jí do poličky opět vrátí, ale kniha je již pro další čtenáře znehodnocená. Příklad v jazyku CL: (volající program) ... dcl &PARMO *CHAR 5 '12345' CALL PGM(A) PARM(&PARMO) /* po návratu je v &PARMO hodnota 'ABCDE' */ .... (volaný program ) A: PGM PARM(&PARMI) DCL &PARMI *CHAR 5 CHGVAR &PARMI 'ABCD' ..... Předávání referencí read-only. Tato metoda je z hlediska přepisu předávané proměnné bezpečnější a tudíž spíše doporučovaná. Pokud je to možné, předá se do volaného programu opět pouze ukazatel na předávanou hodnotu, ale kompilátor zabezpečí, aby tato paměť byla pro volaný program přístupná pouze pro čtení. Porovnáme-li tuto metodu s postupem vypůjčení a čtení knihy v knihovně. Je to asi případ, kdy si čtenář knihu vypůjčí, ale čte jí pod dohledem personálu knihovny, který zabezpečí, aby se s knihou nic nestalo. 13 / 24 Předávání parametrů Common Česká republika 2008-05-20 Předávání honotou. Kompilátor zajistí, aby se před předáním parametru vytvořila jeho kopie. Její hodnota se pak předá do volaného programu. Je to opět metoda zamezující přepisu proměnných, ve kterých se parametry předávají. Je ale ze všech nejpomalejší. Pro příměr s knihovnou je to asi totéž, jako když si čtenář v knihovně koupí svůj vlastní výtisk požadované knihy. S tím si pak může dělat co chce, aniž by přitom jakkoliv ovlivňoval další čtenáře. Jednotlivé možnosti předávání v jazyku CL Povel CALL Pro předávání konstant platí stejná pravidla jako pro použití CALL povelu na povelové řádce. V OPM na rozdíl od ILE program abnormálně končí v okamžiku, kdy je vyvolán program a počet nebo typ předávaných parametrů mezi volajícím a volaným programem nesouhlasí. V ILE dojde k přerušení teprve v okamžiku, kdy se s chybějícím nebo vadným parametrem začne pracovat. Povel CALLPRC Povel CALLPRC může být použit pouze v CL programu typu CLLE (ILE). Oproti CALL povelu nabízí následující rozšíření: • Umožňuje specifikovat volání hodnotou. Tato skutečnost se zadá pomocí klíčového slova *BYVAL za parametrem. • Nabízí specifikaci symbolibké proměnné, do které bude přenesena návratová hodnota poté, co volaná procedure skončí. Jméno symbolické proměnné se uvede u klíčového parametru RTNVAL. Charakteristiky proměnné, která přijímá vrácenou hodnotu by měly být shodné s těmi které jsou definovány u volané procedury. Pokud volaná procedura vrací nějakou hodnotu a ve volající proceruře volané pomoví CALLPRC není pro tuto hodnotu specifikována proměnná (RTNVAL není použit) nevede to k bezprostřední chybě. Pokud je v RTVAL název symbolické proměnné specifikován, ale typ proměnné je jiný nežli je typ vracené hodnoty, skončí návrat abnormálně s hlášením MCH3601. Pokud je typ řetězec znaků, ale je jiná přesnost dojde u řetězců k useknutí nebo doplnění. U číselných proměnných je třeba, aby byla přesnost stejná, jinak konverze vrácené číslo změní! Například při definici proměnné RTNVAL *DEC (5 3) a vracené hodnotě s přesností (4 4) se při návratu hodnoty 0.3333 do proměnné dostane číslo 3.3! • Pomocí hodnoty *OMIT je možno specifikovat skutečnost, že příslušný parametr není při volání použit. Do volané procedury se přenese Pointer nulové hodnoty. • Při předávání parametrů se může přenášet i přenáší i tak zvaný "Operational descriptor" popisující parametry. Pomocí API CEEDOP je možno v okamžiku zavolání zjistit některé údaje o předávané hodnotě a podle toho přizpůsobit další zpracování. Ilustrační příklad je k dispozici pod názvem KCEEDOD. KCEEDOD: Zdrojový kód Zdroj modulu KCEEDOD a jeho vytvoření 14 / 24 Předávání parametrů Common Česká republika 2008-05-20 KCEEDOD: PGM PARM(&TEXT)/* &TEXT must be specified. unpredictable if it is omitted.*/ DCL VAR(&TEXT) TYPE(*CHAR) LEN(50) CALLPRC PRC(PROC1) PARM('0') CALLPRC CALLPRC ENDPGM Results will be + PRC(PROC1) PARM('1' &TEXT) PRC(PROC1) PARM('1' 'Goodbye') CRTCLMOD MODULE(KPLIB/KCEEDOD) SRCFILE(KPLIB/QCLSRC) DBGVIEW(*SOURCE) Zdroj modulu PROC1 a jeho vytvoření PROC1: PGM PARM(&P1 &P2) /* PROC1 - Procedure with optional parameter &P2 */ DCL VAR(&P1) TYPE(*LGL) /*Flag which indicates whether or not &P2 will be + specified. If value is '1', then &P2 is specified */ DCL VAR(&P2) TYPE(*CHAR) LEN(50) DCL VAR(&MSG) TYPE(*CHAR) LEN(50) DCL VAR(&PARMPOS) TYPE(*CHAR) LEN(4) /* Parameter position for CEEDOD*/ DCL VAR(&PARMDESC) TYPE(*CHAR) LEN(4) /* Parameter description for CEEDOD*/ DCL VAR(&PARMTYPE) TYPE(*CHAR) LEN(4) /* Parameter datatype from CEEDOD*/ DCL VAR(&PARMINFO1) TYPE(*CHAR) LEN(4) /* Parameter information from CEEDOD */ DCL VAR(&PARMINFO2) TYPE(*CHAR) LEN(4) /* Parameter information from CEEDOD */ DCL VAR(&PARMLEN) TYPE(*CHAR) LEN(4) /* Parameter length from CEEDOD*/ DCL VAR(&PARMLEND) TYPE(*DEC) LEN(3 0) /* Decimal form of parameter length*/ IF COND(&P1) THEN(DO) /* Parm 2 is specified, so use the parm value for the + message text*/ CHGVAR VAR(%BIN(&PARMPOS 1 4)) VALUE(2) /* Tell CEEDOD that we want the operational descriptor for the second parameter*/ CALLPRC PRC(CEEDOD) PARM(&PARMPOS &PARMDESC &PARMTYPE &PARMINFO1 &PARMINFO2 &PARMLEN) /* Call CEEDOD to get the length of data specified for &P2*/ CHGVAR VAR(&PARMLEND) VALUE(%BIN(&PARMLEN 1 4)) /* Convert the length returned by CEEDOD to decimal format*/ CHGVAR VAR(&MSG) VALUE(%SST(&P2 1 &PARMLEND)) /*Copy the data passed in to a local variable*/ ENDDO ELSE CMD(CHGVAR VAR(&MSG) VALUE('Hello')) /* Use "Hello" for the message text*/ SNDPGMMSG MSG(&MSG) ENDPGM CRTCLMOD MODULE(KPLIB/PROC1) SRCFILE(KPLIB/QCLSRC) SRCMBR(KPROC1) DBGVIEW(*SOURCE) CRTPGM PGM(KPLIB/KCEEDOD) MODULE(KPLIB/KCEEDOD KPLIB/PROC1) 15 / 24 Předávání parametrů Common Česká republika 2008-05-20 obsah symbolických proměnných po zavolání: call kplib/kceedod parm('Call ILE main and ILE PROC1') Hello Call ILE main and ILE PROC1 Goodbye &P2 = 'Call ILE main and ILE PROC1 EVAL &PARMLEN:x 00000 00000032 ........ ........ . EVAL &PARMLEND &PARMLEND = 007. &P2 = 'Goodbye Jednotlivé možnosti předávání parametrů v jazyku RPG V RPG je možno volat programy nebo procedury. Program je z hlediska ILE hlavní procedurou, která má ale některá omezení. Hlavní procedura nemůže například vracet hodnotu. Pro proceduru i hlavní program je pro případ předávání parametrů vždy zapotřebí připravit call interface. Ten může být obecně buď jednodušší (*ENTRY PLIST) nebo robusnější (PROTOTYP). Srovneme oba typy interface: Copy člen: Hlavní program kde je použit interface typu PROTOTYPE: 16 / 24 Předávání parametrů Common Česká republika 2008-05-20 A stejný program využívající interface typu *ENTRY PLIST: Základní rozdíly mezi prototypovým a neprototypovým interface uvádí následující tabulka: Jak je patrné možnosti prototypového volání jsou bohatší. Prototypové volání Prototyp je externí call interface umožňující kontrolovat správné zadání volání již v době kompilace programu. To je jeden z důvodů proč se tento způsob volání doporučuje. Stejným způsobem se volají vestavěné funkce. Prototypové volání je možno použít na • volání programů, přítomných v systému v době volání • volání exportovaných procedur z ostatních modulů nebo servisních programů, které jsou připojeny (pojem bound, který znamená symbolické připojení) • volání podprocedur stejného programu 17 / 24 Předávání parametrů Common Česká republika 2008-05-20 Pro pojem prototypové volání se rovněž používá pojem "Volné volání", který vychází z toho, že předávané parametry se zapisují do závorky volně, odděleny čárkami. Prototypové volání se realizuje příkazem CALLP nebo voláním jménem funkce. Prototypové volání předávání parametrů Již v době překladu je kontrolována shoda prototypu na straně volaného a volajícího programu. Volání je jednosušší, protože nevyžaduje další povely typu PARM. Způsoby předávání parametrů Při volání programů včetně systémových API se používá předávání referencí. Při volání procedur je možno použít libovolnou metodu (referencí, referencí read only nebo hodnotou). Zatímco při předávání referencí se u parametrů neuvádí žádná klíčová slova - tento způsob se automaticky předpokládá, u předávání referencí read only a předávání hodnotou se u příslušných parametrů používají klíčová slova CONST respektive VALUE. Výhody předávání parametrů referencí-read only a hodnotou: • Možnost předávat na místě parametrů konstanty i výrazy. • Možnost předávat parametry, které svými charakteristikami nemusí úplně odpovídat charakteristikám přijímající strany. • Záruka, že proměnné předané jako parametry nebudou po předání jakkoliv modifikovány. Příkladem může být následující situace: Parametr je definován jako *DEC (5 2). Při volání je třeba předat numerickou hodnotu, ale nemusí to být přesně *DEC (5 2) ale i • Pakovaná, zónová nebo binární konstanta nebo proměnná, s libovolnou přesností. • Vestavěná funkce, která vrací numerickou hodnotu. • Procedura vracející numerickou hodnotu. • Numerický výraz například : 2 * (Min(Length(First) + Length(Last) + 1): %size(Name)) Dalším příklad illustruje možnosti předávání pole: V prototypu je definován parametr typu pole o čtyřech elementech. Předávaný parametr může být: Pole, které má méně než čtyři elementy. Zbývající elementy budou obsahovat default hodnotu příslušnou pro daný typ dat. Pole o čtyřech elementech. Absolutní shoda. Pole, které má víc než čtyři elementy. Nadbytečné elementy se nepřenesou. Proměnná nebo konstanta, která není polem. V tom případě se touto hodnotou obsadí každý element pole. Použití Operačního popisu Někdy je zapotřebí předávat parametr, ke kterému je, vzhledem k různým variantám volání, nezbytné přidat i jeho popis (operační popis). Volaná procedura zvolí způsob zpracování na základě tohoto popisu. Je zřejmé, že volaná procedura musí být na přijetí tohoto popisu připravena. Řada bindable API skutečně s takovým popise pracuje(např. CEEDATM). Kompilátor RPG v současné době poskytuje operační popis pouze pro proměnné typu řetězec, grafická pole a podpole. Operační popis je možno použít u prototypového i neprototypového způsobu volání. U prototypového volání použijeme u příslušného parametru klíčové slovo OPDESC. 18 / 24 Předávání parametrů Common Česká republika 2008-05-20 Příklad : U neprototypového volání specifikujeme u povelu CALLB "D". (viz dále) V obou případech se operační popis přenáší jako skrytý parametr a jeho hodnota se zjišťuje pomocí API CEEDOD (viz příklad KCEEDOD) a CEESGI. Vynechávání parametrů Při volání procedury se může vyskytnout případ, kdy potřebujeme některý parametr vynechat. Tato situace je běžná při volání API, ale může to být i případ vývoje nějaké procedury, kdy staré programy, které nechceme a nebo dokonce nemůžeme měnit neumějí zacházet s novými parametry, které se byly během vývoje do procedury díky požadavkům aplikace přidány. V takovém případě je možno volit mezi možnostmi: • Specifikovat OPTIONS(*OMIT) u parametru a na místě parametru při volání uvést *OMIT. • Specifikovat OPTIONS(*NOPASS) u parametr při volání úplně vynechat. V obou případech se s takovým parametrem ve volané proceduře nedá pracovat. Rozdíl je v tom, že parametr předaný jako *OMIT se započítává do počtu předaných parametrů. Hodnota *OMIT se do volané procedury může přenášet pouze referencí! Ke zjištění, zda-li byla předaná hodnota *OMIT se používá vestavěná funkce %ADDR, která v tom pžípadě vrací hodnotu *NULL, nebo API CEETSTA. Pokud zvolíme možnost vynechání parametru, je nutno dodržet zásadu, že u všech parametů za prvním, kde se použije OPTION(*NOPASS), je tato volba rovněž použita. Kontrola počtu parametrů Někdy je zapotřebí aby procedura byla navržena pro volání s různými počty parametrů. Na jejím začátku je třeba tento počet zjistit. K tomu složí vestavěná funkce %PARMS. Ta vrací počet parametrů a v případě, že se nedá zjistit, vrátí hodnotu -1. Parematr s hodnotou *OMIT se počítá do počtu parametrů. Předávání menší porce dat než je požadováno Tato možnost je při předávání parametrů ošetřena pomocí OPTIONS(*VARSIZE). Pozor na omezení: *VARSIZE je možno použít jen pro řetězce, pole UCS-2, grafická pole a nebo pole grafických polí. 19 / 24 Předávání parametrů Common Česká republika 2008-05-20 příklad: Pořadí, ve kterém se vyhodnocují hodnoty parametrů ve volaném programu Pořadí vyhodnocování hodnot parametrů ve volané proceduře se nedá žádným způsobem zajistit. To je důvod, proč je třeba při složitých voláních ověřit, jak bude vyhodnocování postupovat, aby nedošlo k nepředpokládaným vedlejším efektům. Ty mohou nastat pokud se při zpracování parametrů změní: • Hodnota referenčního paremetru • Hodnota globální proměnné • Externí objekt - soubor, nebo data area Vznik takového vedlejšího efektu má za následek, že se do zpracování nedostane předpokládaná hodnota parametru. Předpokládejme následující volání: CALLP procA (fld : procB(fld) : fld) Procedura procA používá u všech parametrů předávání hodnotou. Procedura procB používá předávání referencí. Na počátku bude v fld hodnota 3. procB změní tuto hodnotu na 5 a vrátí hodnotu 10. Skutečně předané hodnoty budou záviset na pořadí vyhodnocování parametrů a mohou být různé! (3, 10 a 5 nebo 3, 10 a 3 nebo 5,10 a 3 nebo 5, 10 a 5)!! Okolnosti, nastávající při předávání parametrů mezi různými programovacími jazyky. V případě, že se předávají parametry mezi programy a procedurami napsanými v různých programovacích jazycích je třeba zkontrolovat • zda-li v nich jsou podporovány stejné metody předávání parametrů • zda-li typy dat použité k předávaná parametrů jsou shodné Následující tabulky dávají přehled o možnostech předávání parametrů v jednotlivých, na AS/400 používaných jazycích. 20 / 24 Předávání parametrů Common Česká republika 2008-05-20 Neprototypové volání 21 / 24 Předávání parametrů Common Česká republika 2008-05-20 K dispozici jsou povely CALL pro volání programů a CALLB pro volání bound procedur. Neprototypové volání se doporučuje používat pouze tehdy pokud: • Se jedná o jednoduchý případ volání • Je nutné využí možností, které poskytuje operace PARM (operandy 1 a 2) • Je třeba mít při volání vetší volnost, než poskytuje použití prototytu Formálně jsou oba povely velice podobné, 1. V povelu se specifikuje volaný objekt(faktor 2) 2. Volitelně se specifikuje chybový indikátory (pos. 73 a 74) a-nebo LR indikátor (pos.75 a 76) 3. Předávané parametry se specifikují pomocí PLIST v poli Result, nebo pomocí PARM operace, která bezprostředně následuje. Příklady CALL: Přiklad CALLB: Při použití neprototypového volání je třeba mít na zřeteli následující skkutečnosti: Na místě názvu volaného objektu(faktor 2) se může použít proměnná, konstanta, nebo jméno konstanty. V tomto poli se rozlišují velká a malá písmena! Pouze pro CALL platí: Na místě operandu faktor 2 se může použít kvalifikovaná notace(library name/program name). Jméno programu je možné umístit do řetězcové proměnné. Pouze pro CALLB platí: Pokud se na místě operandu faktor 2 použije pointer obsahující adresu procedury, jedná se o tak zvané statické volání s ukazatelem. V proceduře se může vyskytovat více CALLB volání stejné procedury se stejnými nebo jinými parametry. Proměnné jsou inicializovány pouzy při prvním zavolání. Jejich obsah je pro druhé a další zavolání takový, jaký je zanechalo předchozí volání. 22 / 24 Předávání parametrů Common Česká republika 2008-05-20 konec 23 / 24 Předávání parametrů Common Česká republika 2008-05-20 Seznam použitých zdrojů: 1) Call RPG Procedures from CL. Hey, Ted 2) CLLE's CALLPRC Command CLLE, Robert Cozzi,11 November 2003 3) Big Blue delivers promises CL enhancement in V5R4, Paul Tohy, 01 September 2006 4) Optional Parameters and CL procedures, Hey, Ted 5) Subprocedures - Tips and Technics, Bradley V. Stone 6) Safely and reliably Passing CL Parameters, Dahn Riel, 1995, 1996 7) Passing Parameters with ILE RPG Subprocedures, Craig Pelkie 8) ILE RPG Programmers' Guide, Version 5, , SC09-2507-05 9) ILE RPG Reference, Version 5, , SC09-2508-05 10) System i Programming Control Language V5R4, Sixth Edition (February 2006) 11) iSeries Cl Programming, Version 5, SC41-5721-06 12) Powerful Stuff: Creating Commands with Variable-Length Parameters!, Ted Holt, 29 November 2006 24 / 24
Podobné dokumenty
Candida albicans IgA ELISA
nakláněním nebo kýváním lahvičky. Vyhněte se dynamickému třepání, které
vede k tvorbě pěny.
Je důležité pipetovat reagencie ve stejných intervalech, aby ve všech jamkách
mikrotitrační destičky by...
Programovatelné obvody, trendy, projekty FEL
Hardware Description Language (HDL):
• Firemní jazyky: např. ABEL, AHDL
• VHDL - IEEE Std 1076 (1987, 1993, 2000, 2002, 2008)
• Verilog HDL - IEEE Std 1364 (1995, 2001, 2005)
• SystemVerilog HDL - ...