Delphi XE6, postřehy z praxe pohledem JaroB

vložil Jaro Beneš 2. května 2014 21:56

Rychlost vydání nové verze Delphi kapku překvapila. XE5 vydaná v září 2013 se možná ani nestačila zabydlet v komerčních projektech (co si budeme povídat, z obchodního hlediska je stále ještě kladen důraz na jistotu a stabilitu aplikací) a už je tady nová verze. Z hlediska vydání ale vzniká dojem, že verze XE5, XE4 a XE3 byly možná jen prologem ne-li prerequelem právě pro novou XE6-ku!

Co očekávat?

Asi hlavním tahákem této nové verze je stabilizace a opravy chyb napříč aplikací - opraveno na 2500 chyb, z čehož je pětina přetrvávajících ze starých verzí. Integrované prostření dostalo nový kabátek a funkci kompilace na pozadí.

Ovšem největší novinkou je App Tethering, zjednodušeně řečeno propojení aplikací na různých platformách pomocí HTTP a REST v nejrůznějších kombinacích využitím specializovaných komponent. Otvírá se tím možnost jednoduchým způsobem komunikovat mezi aplikacemi na různých platformách a přenášet mezi nimi různá data, sdílet je nebo volat různé metody.

Pro webbroker je možné opět využít Apache Server (pozn. RC: podporováno je rozhraní A2.0, A2.2 a A2.4) a změny doznalo i samotné VCL. Zde zamáčknu slzu, rovnou ve zdrojových adresářích se objevily soubory s překladem systémových konstant, bohužel jenom do němčiny, francouzštiny a japonštiny.

Vizuální knihovna komponent byla rozšířena o komponent taskbaru, který zapouzdřuje funkce pro Taskbar Windows 7 a 8 s využitím tlačítek. Rovněž přibyla jednotka pro systémové styly určená pro změnu vzhledu nabídkových menu v duchu vybraného stylu (vlastně téměř totéž, co vytvořil Rodrigo V. Ruz / pozn. RC - to bude tím, že EMBT to od něj licencovalo). Dva nové styly Glossy a TabletDark rozšiřují paletu stylů VCL a určitě zlepšují vnímání aplikace uživatelem (to mohu potvrdit, jednu z mých aplikací používá kolem pěti tisíc uživatelů a více jak polovině z nich se zobrazuje některý ze tří v aplikaci přednastavených stylů).

Nové jsou hlavičkové soubory D3D DirectX 11 a OpenGL Ex a také jednotka System.Math.Vectors, kde je většina operací a transformací pěkně pohromadě. A JSON je nyní součástí systémových rutin.

S tím zřejmě souvisí další přesuny v jednotce SysUtils a vyčleňování specifických rutin (AnsiStrings), ale netřeba se obávat, že by SysUtils jako taková zhubla. Při letmém srovnání zdrojových kódů z XE5 a XE6 vyplynula nápadná neshoda v adresáři Firemonkey (FMX), v XE6 doznala výrazného rozšíření resp. restrukturalizace, a tak se trochu strukturou začíná přibližovat k VCL. Aplikace na bázi Firemonkey umožňuje umístění reklam přímo v aplikaci a rovněž on-line platby. Taktéž kreslící plátno podporované výkonem GPU, které bylo dostupné jen na mobilních zařízeních, je možné nově využít i v desktopových aplikacích FMX pro Windows.

Aplikace VCL mohou využít senzory stejně jako doposud aplikace Firemonkey. Senzorové komponenty (TLocationSensor, TMotionSensor, TOrientationSensor a případně další) jsou nyní umístěny v paletě komponent a lze je plně integrovat do aplikace VCL, viz:

senzor

WebBrowser byl aktualizován na poslední verzi Internet Exploreru ve Windows. A za tím vším je spousta dalších a dalších drobných vylepšení až na úroveň RTL.

Instalace, registrace

Instalace proběhla naprosto bez problémů (měl jsem k dispozici jak ISO, tak možnost web instalace), zvolil jsem možnost instalovat z trialu. Trial funguje na kód, který zasílá Embarcadero registrovaným uživatelům po dobu 30 dnů, a to je opravdu seriózní nabídka k vyzkoušení.

Já ale použil kód z placené verze. Po nainstalování všech součástí aplikace a prvním spuštění se zobrazil relativně přívětivý registrační formulář. Oproti starším verzím poněkud zjednodušený, a ten asi většina uživatelů přivítá. Po zaregistrování jsem už mohl spustit vlastní aplikaci.

První postřehy a dojmy

Velmi pozitivně mě překvapil čas náběhu aplikace, a to mohu porovnat, na svém stroji mám nainstalováno devět souběžných verzí Delphi. Je srovnatelný, ne-li rychlejší jak v Delphi XE2. Naopak nejpomalejší se mi jeví start v XE3 a XE4. To je asi daní za první verze testu konzistence knihoven v adresáři binárek té které verze Delphi (lze to asi chápat i jako ochranu před kopírováním).

Vzhled aplikace se taky vylepšil, i když je to menší překvapení ze vzhledu prostředí IDE, než bylo při přechodu od Delphi 7 k Delphi 2005 (uživatelé Delphi 8 laskavě prominou). Toolbar i palety IDE mají oproti předchozí verzi jiné ikony, vypadají líbivěji a jsou spíš ve stylu poslední verze Windows.

IDE

Ale jsem programátor, který vytváří především aplikace VCL pro Windows, takže zkusím, jak si nové Delphi stojí v této, za posledních pár verzí zpět opomíjené a příliš nezdůrazňované oblasti.

Praktická zkouška úvodem

Rozhodl jsem se zkusit prakticky naimportovat vcelku dobře známou knihovnu DelphiX, tedy prastarý framework pro psaní plošinovek a jiných herních hříček. Využil jsem mnou upravenou verzi tzv. (un)DelphiX, kterou vlastně průběžně upravuji už od verze Delphi 6 a pokusil se ji adaptovat. Upravil jsem pouze hlavní soubor include, kde je nutné nastavit novou verzi Delphi jednoduchou direktivou

{$IFDEF VER270}….{$DEFINE VER20UP}{$ENDIF}

, aby bylo možné tuto verzi držet pro výjimečné situace (co kdyby se v této verzi nějaké programové konstrukce změnily). Práci jsem si poněkud ulehčil, použil jsem verzi odladěnou již v XE5.

Nutnou podmínkou bylo vytvoření nového balíčku. Zvolil jsem jméno v intencích předchozích balíčků jako DelphiX200.dpk, vložil požadované programové jednotky a pokusil se o první překlad.

Překlad proběhl uspokojivě a balíček se vytvořil. Po instalaci se objevil standardní informační dialog o nainstalování do IDE (jenom podotýkám, DelphiX má pouze jeden kombinovaný balíček).

balíček

Jenom pro pořádek připomínám, že je nezbytné přidat cestu do Tools > Options > Environments Options > Delphi Options > Library > editační pole Library Path na zdroje, případně na přeložené DCU, aby je IDE vidělo a nehlásilo, že nemůže příslušné dcu nalézt. Velmi se mi osvědčilo vytvořit v environment (Tools > Options > Environments Options > Environment Variables) novou proměnnou, pojmenovanou např. DLIB, která směřuje na konkrétní bázový adresář, řekněme C:\DELPHI_XE6 a kterou je možné použít jako alias i pro nastavení cesty na zdroje, viz záznam $(DLIB)\DelphiX\source.

Abych se přesvědčil o správné funkci v IDE, otevřel jsem demo projekt SpriteShot z DelphiX, zkusil jej přeložit a rozběhnout.

Po otevření projektu IDE chviličku „přemýšlí“ a teprve poté otevře hlavní formulář aplikace. Pokud nejsou nastaveny cesty na zdroje, pak zde ohlásí nedostupnost programových jednotek (to bývá obvyklá chyba prostoru jmen, mnohdy stačí doplnit VCL namespace) nebo neznámé komponenty na formuláři (pokud jsou využity komponenty z jiných, ještě nenainstalovaných balíků):

DelphiX

Jen malá poznámka, od verze Delphi 2010 využívá framework zabudované hlavičkové soubory DirectX, které poskytuje přímo Delphi. Tím se eliminuje nutnost upravovat původní programové jednotky hlavičkových souborů založené ještě na DirectX7.

Takto jsem si ověřil, že lze využít i poměrně starý, ale funkční programový kód, byť za jistých specifických podmínek (vytvoření nového balíčku, upravení souboru include a dopsání definice pro novou verzi Delphi). To se ale musí udělat v podstatě pro každou knihovnu třetí strany, kterou původní autoři léta neudržují, ale která v určitých komunitách uživatelů stále žije.

Instalace JCL

Knihovnu JCL, která zapouzdřuje velké množství volání API a přizpůsobuje to přirozenému jazyku Object Pascalu, považuji za zcela nezbytnou. Někdo z ní použije třeba jen hlídání jedné instance, někdo správu pro VersionInfo, jiný zase zapouzdření souborů mapovaných do paměti. Záleží prostě na konkrétním vývojáři a situaci, kterou si chce vůči systémovým API Windows (a nejen jim) ulehčit.

Lehce mě překvapilo, že se aktualizovaná verze objevila téměř souběžně s novými XE6-mi, stejně tak jako všeobjímající a skoro vše zahrnující knihovna JVCL. Jen na okraj, v JVCL jsou soustředěny knihovny, o které se jejich původní autoři nestarají a jejichž kód bloudil po různých internetových úložištích jako je třeba torry.net, vclcomponents.com a podobných. Každopádně i JVCL je pořádné dělo, které spřístupňuje pro aplikační programátory stovky komponent pro nejrůznější situace, samozřejmě za určitou cenu (za hlavní nevýhodu osobně považuji nemožnost použít jenom část frameworku, asi díky systému prapředků všech komponent a jejich kontrolerů), kterou vyžaduje tak rozsáhlý framework jakým JVCL bezesporu je.

Na co si dát pozor

Rád bych upozornil, že při instalaci knihovny JCL, a nejen této knihovny, je nutné mít na paměti, že XE6 má jiné bázové adresáře, tj. RAD Studio se změnilo na Studio a změnu doznal i adresář na BPL/DCP soubory, viz „c:\Users\Public\Documents\Embarcadero\Studio\14.0\“ na rozdíl od adresáře pro XE5, viz „c:\Users\Public\Documents\RAD Studio\12.0\“. Je to dost zásadní rozdíl, především pro instalační programy balíků komponent.

Známá knihovna RxLibrary

Domnívám se, že tuto knihovnu není potřeba příliš představovat, neboť její podmnožina se stala i součástí obrovského balíku komponent JVCL. Tedy snad jen jednou větou. Knihovna obsahuje desítky užitečných komponent z oblasti VCL, DB a BDE nesmrtelné a umožňuje využít i taková rozšíření jako jsou zásuvné moduly, vícejazyčné formuláře nebo líbivější vizuální komponenty, které v původní knihovně ani nenajdete.

Opět jsem vycházel z verze XE5, instalace je složitější, neboť knihovna má tři runtime a tři designtime balíky. Vytvořil jsem tedy nové balíky a upravil základní soubor include knihovny. A zkusil to přeložit. Problémy, které jsem očekával v oblasti zabudovaných jazykových souborů, kterých je v knihovně vložených dvacet šest, se nenaplnily, ale vyskočila jiná chyba, díky které jsem zjistil, že Embarcadero přeskočilo 13-ku (asi z důvodu jisté pověrčivosti) ve verzování Studií a následující je tedy číslo 14 včetně zápisu v registrech! Po doplnění překlad proběhl uspokojivě.

Záměrně píši uspokojivě. Překladač oznámil pár deprecated funkcí (tj. funkcí či symbolů, které zatím ještě fungují, ale v některé z budoucích verzí mohou být odstraněny) v souvislosti s přesunem výkonného kódu kolem AnsiStringů.

Větší starost mi činí hlášení kolem datasetů, viz příklad:

[dcc32 Warning] RxLookup.pas(1084): W1000 Symbol 'GetFieldList' is deprecated: 'Use overloaded method instead'
[dcc32 Warning] RxMemDS.pas(741): W1000 Symbol 'InitRecord' is deprecated: 'Use overloaded method instead'
[dcc32 Warning] RxMemDS.pas(775): W1000 Symbol 'GetCalcFields' is deprecated: 'Use overloaded method instead'
[dcc32 Warning] RxMemDS.pas(919): W1000 Symbol 'Validate' is deprecated: 'Use overloaded method instead'
[dcc32 Warning] RxMemDS.pas(1269): W1000 Symbol 'DefaultFields' is deprecated: 'Use TField.LifeCycle or TFields.LifeCycles properties instead'
[dcc32 Warning] RxMemDS.pas(1284): W1000 Symbol 'DefaultFields' is deprecated: 'Use TField.LifeCycle or TFields.LifeCycles properties instead'

Tato hlášení jsou ve většině případů důsledkem změny typů bázových bufferů v datasetu (prapůvodně stačil PChar jako ukazatel na data, který se v unicode verzích Delphi transformoval na pravá pole) a jeho klonech a jsou zakryta změtí overloadovaných a overridovaných metod různých předností. Tohle asi není úplně jasně ze strany Embarcadera komunikováno a chybí ty správné vzory (patterns) pro třetí strany, jak přejít z jednoho vzoru na nový. V mnoha případech postačuje prosté přetypování nebo doplnění generické třídy (např. pro Fields). Ale jinak nevím, nevím…

Pozn RC: No to není tak úplně pravda. Jedná se o důsledek toho, že TDataset by měl nyní umožňovat používat persistentní Fields, tj. můžete v době návrhu nadefinovat několik fieldů a zbytek se vytvoří za běhu - osobně jsem ale nezkoušel. Jedná se o dlouhodobý požadavek a pokud vím, implementace se ujal sám autor FireDacu (AnyDacu).

Ale zpět, pro ukázku můžeme pohlédnout na paletu s nainstalovanými komponenty:

RX

Tiskové řešení QuickReport

V době vyzkoušení jsem neměl k dispozici originální úpravy pro XE6 od QBSoftware, tak jsem použil poslední verzi 5.0.6. z ledna 2014. V této verzi se vývojáři pokusili opravit některé chronické chyby, ale ani po čtrnácti letech se jim nezdařilo přemigrovat experty pro pomoc při výstavbě nového reportu či napojení na databázový zdroj. A taky by mohli aktualizovat MSXML_TLB.pas, protože je to už pro ostudu. Nicméně, postupoval jsem zcela identicky jako v předchozích případech. QuickReport využívá rovněž globální include, který je nezbytné upravit. Rovněž je vhodné vypnout implicitní odkazy na BDE nesmrtelné (omlouvám se za ironický výraz na adresu BDE), zde jenom upozorňuji, že originální zdroje nejsou důsledné, v designtime toto nevypínají, neb jim chybí kód pro přesměrování z BDE (např. na DataSnap).

Lokální databáze

Jako lokální databázi jsem naimportoval jednoduchou souborovou databázi TinyDB (prosím nezaměňovat s jinou TinyDB, která má být, cituji: „deklarativní dotazovací procesový systém pro získávání údajů ze síťových senzorů TinyOS“). Knihovnu lze použít jako jednoduchou náhradu za BDE nesmrtelné nebo se s tím dají perzistentně ukládat data namísto jiných úložišť (např. INI, XML atp.) protože je to de facto DBAware systém.

Jelikož většina zásadních chyb týkajících se datasetu byla odladěna v Delphi ve verzích XE2 a v XE3 (kde asi proběhly nejbouřlivější změny „pod fasádou“), tak vlastní instalace knihovny proběhla opět velmi jednoduše a bez chyb.

Závěr z importu knihoven komponent třetích stran

Na základě zkušenosti s adopcí knihoven třetích stran mohu konstatovat, že kompatibilita s předchozí verzí Delphi je v podstatě stoprocentní. IDE bylo stabilní i přes všechna kouzla, která jsem prováděl s projektovými soubory (i když poučen z minulých verzí, preventivně jsem zdroje ukládal).

Pro společný test všech knihoven jsem využil jednu z mých stávajících aplikací o rozsahu cca 350000 řádků. Jsou v ní volány rutiny z výše popsaných knihoven a frameworků, a využity specifické vizuální komponenty.

Jak jsem již zmiňoval výše, specifické dialogy a texty jsou již lokalizovány Embarcaderem do japonštiny, francouzštiny a němčiny jako standard. Jelikož čeština je okrajový jazyk, tak jsem toto napravil a počeštil alespoň ty nejzákladnější dialogy.

Suma sumárum, přechod na novou verzi Delphi XE6 mi trvala i s přechodem komponent třetích stran výše popsaných cca 3 hodiny čistého času. V podstatě to byl nejrychlejší převod knihoven a aplikací na novou verzi, kterou jsem kdy dělal. Ale ještě jednou zdůrazňuji, převáděl jsem knihovny a frameworky z předchozí verze Delphi XE5 na XE6.

Úskalí převodu non-unicode knihovních kódů

Jistě existuje spousta vývojářů, kteří setrvávají na starších verzích Delphi, jednoduše proto, že převod knihoven třetích stran, použitých ve vlastních aplikacích, mnohdy neudržovaných, je problematický, unicode verze neexistují a bez znalostí nízkoúrovňových zákonitostí těch kterých knihoven a frameworků mnohdy zcela nemožný.

Samozřejmě že lze zkusit převést kód tak zvaně „naslepo“, využít všech firemních doporučení Embarcadera a upravit kód tak, aby po překladu nevykazoval žádné hlášení a varování. Platí jednoduché pravidlo, čím je kód starší, resp. z nižší verze Delphi pochází, tím je převod složitější. Jako minimum se dneska považuje Delphi 5, ale nejsou výjimečné případy kódu z Delphi 3 nebo i Delphi 2! Co určitě nebude z takto starých verzí Delphi fungovat, jsou kódy tzv. expertů, systémových dialogů a designtime editorů. Už problematický byl přechod na nový systém rozhraní IDE OTA Delphi 6, po drobných úpravách je možné kódy pouze správně přesměrovat, ale vyžaduje to něco magie v sekcích uses jednotlivých registračních unit.

Jako příklad uvádím uses registračního souboru RxToolReg z knihovny RxLibrary:

uses
  Classes, SysUtils, Controls, Graphics, TypInfo, Consts, Dialogs, ExtCtrls,
  RxPictEdit, RxHook, RxPicClip, RxPlacemnt, RxPresrDsn, RxMinMaxEd, RxDualList,
  RxClipView, RxSpeedbar, RxSbEdit, RxDataConv, RXCalc, RxPageMngr, RxPgMngrEd, RxMrgMngr,
  RxStrHlder, RXShell, RxAppEvent, RxVCLUtils, RxTimerLst, RxTimLstEd, RxIcoList, RxIcoLEdit,
  {$IFDEF RX_D6}RxPlugin, RxPluginManager, RxPluginWizard, RxPluginParamsForm, {$ENDIF}
  {$IFDEF USE_RX_GIF} RxGIF, RxGIFCtrl, {$ENDIF} RxResConst, RXCtrls, RxRichPopup, RxCalcEditDlg,
  {$IFDEF RX_D3} RxResExp, {$ENDIF} RxMenus, RxMRUList, RxMailBox, RxTranslate, RxNTSecurity,
  {$IFNDEF VER80} RxNotify, RxGrdCpt, RxGradEdit, {$ENDIF} RxHintProp, ToolsAPI, RxViewer,
  {$IFDEF RX_D6} RTLConsts, DesignIntf, DesignEditors, VCLEditors {$ELSE} DsgnIntf {$ENDIF};  

Čistě teoreticky by bylo možné přeložit kódy i v šestnáctibitových Delphi 1, ale kdo to dneska potřebuje, že?

Každopádně je nezbytné zaměnit původně jedinou jednotku DsgnIntf za variaci jednotek RTLConsts, DesignIntf, DesignEditors, VCLEditors příp. dalších. Samozřejmě, nemusí být použity všechny, ale pouze ty nejpotřebnější, takže pokud nejsou využity editory vlastností nebo komponentů, tak je možné je vypustit (při nějaké optimalizaci).

Pokusím se popsat převod non-unicode knihovny HighGear 2.0, kterou jsem kdysi dávnou koupil jako bonus plus s Delphi 3. Rozhodl jsem se, že to bude cesta bez návratu, tudíž se nové zdroje nedají v Delphi 3 už přeložit.

Pokud je k dispozici Delphi 2006/2007, silně doporučuji využít toho jako mezistupeň a dotlačit kód na tyto poslední non-unicode verze a z ní se teprve pokusit o přeskok na plnou unicode verzi. Dobrým cvičením je také překlad v Delphi 2007 for .NET, tedy verze plně podporující Unicode à la Delphi 2009, ale se specifiky pro .NET.

Co se musí udělat jako první.

1/ Především se musí oddělit kódy pro designtime a runtime. Ze všech jednotek, které budou sloužit jako runtime, se musí odstranit kód editorů vlastností a komponentů a shrnout ho do jedné registrační jednotky a z uses se musí vyrazit jednotka DsgnIntf. Tuto knihovnu jsem už kdysi portoval do Delphi 6, takže určitou část práce jsem měl hotovou (je poměrně náročná na čas).

2/ Projít všechny destruktory a ověřit pořadí uvolňování, protože pokud je volán destruktor předka, musí být bezpodmínečně volán poslední – zde bývá často chyba, starším verzím Delphi toto bylo tak nějak jedno, ale nové Delphi jsou v runtime přísné a hned to trestají jako Access Violation (AV).

3/ Projít kód a ověřit, že všechny Free metody jsou ošetřeny v sekvenci try – finally. Rovněž doporučuji ověřit všechny konstruktory, někdy se najdou Create bez uložení instance (setkávám se s tím obvykle u TBitmap nebo TStringList) nebo jim chybí příslušné párové Free. Díky tomu se objeví dost skrytých memory leaks. Samozřejmě doporučuji při té příležitosti prohlédnout všechny konstrukce s with – do, i zde se může vyskytnout problém s nejednoznačností přiřazení.

4/ Projít všechny Move() a ověřit, co přesně kopírují. Pokud kopírují znaky, pak se přidržet doporučení Embarcadera a upravit příslušné úseky kódu. Mnohdy se přijde na to, že kód již není potřeba (především pozor na záměny AnsiChar x UnicodeChar při kopírování do ShortString).

5/ S tím souvisí používání PChar, typicky v kreslících rutinách nebo bufferech. V mnoha případech lze předat rovnou řetězec s přetypováním PChar(string) do API rutin. Osobně doporučuji uzavírat původní kód buď do komentářů, nebo jej vymezit direktivami (nejen kvůli snadnému vrácení v případě chyby, ale hlavně, zůstane nezměněn původní funkční kód a je možné ho prozkoumat v případě problémů po transformaci)

{$IFDEF UNICODE}
//sem nový kód
{$ELSE}
//zde ponechat původní kód
{$ENDIF}

Rovněž doporučuji prohlédnout kód každého komponentu a projít odkazy na vlastní property. Mnohdy se stává, že je volán setter místo jednoduchého přiřazení do pole.

Příklad:

private
  FDiagonal: Boolean;
  procedure SetDiagonal(Value: Boolean);
…
published
  property Diagonal: Boolean read FDiagonal write SetDiagonal;

a v kódu je použito

Diagonal := GetPossibleDiagonal();
namísto
FDiagonal := GetPossibleDiagonal();

Toto přiřazení může být potenciálně nebezpečné, protože setter může obsahovat další přidaný kód, neboť je určen pro nastavění zvnějšku. Samozřejmě je to závislé též na kódu setteru. Někdy bývá volána nějaká forma obnovení stavu komponenty nebo překreslení hned po přiřazení hodnoty. Bývá to častá chyba dvojitého volání (překreslení, zápisu, vedlejší efekt, atp.), protože obdobná funkce je volána hned po přiřazení hodnoty uvnitř setteru a vzápětí pro jistotu ještě vně, viz příklad

procedure TXCross.SetDiagonal(Value: Boolean);
begin
  FDiagonal := Value;
  Invalidate;
end;
…
  Diagonal := GetPossibleDiagonal();
  Invalidate; //chyba, voláno podruhé

6/ V potomcích datasetetů zaměnit PChar buffer za PAnsiChar nebo jak vyžaduje XE6 rovnou TRecordBuffer (dataset má ale větší množství overloadovaných metod). Tato úprava si může vynutit další změny související s prací s bufferem.

7/ vytvoření nové registrační jednotky a shrnutí všech kódů určených pro designtime. Sem se soustředí všechen výkonný kód pro property editory a component editory. Vlastní editory budou vyžadovat úpravy v sekcích uses a protože jsou to samostatné jednotky a formuláře tak možná i nějaké vzhledové úpravy (minimálně nastavení pozice). Doporučuji převést všechny formuláře do textového tvaru.

8/ z IDE Delphi XE6 vytvořit nové balíčky DPK a vložit do nich ručně obsah všech původních jednotek (nezapomenout zahrnout v balíku designtime jednotu DesignIDE, nutno dopsat ručně) a balíky z Delphi označit jako runtime only a designtime only!

Pokud se podařilo uložit balíky, je možné přistoupit k ladění kódu překladem. Není to úplně ideální přístup, ale v tomto případě, nejste-li autorem původního kódu a mnohdy se v něm zas tak nevyznáte, je to účinné řešení, jak objevit podezřelý kód.

Doladění kódu

Pokusil jsem se o první překlad nejprve balíku runtime a potom balíku designtime.

1/ Problém vyvstal s TBookmarkStr. Toto je nutné ošetřit, smysl se tuším od XE3 kapku změnil, zaměnil jsem TBookmarkStr za TBookmark a upravil příslušné seznamy. Původní seznam byl založený na TStringList, nový musí být deklarován jako TList<TBookmark>, a to si vynutilo vložení jednotku System.Generics.Collections do uses. Ostatní kód nebylo potřeba upravovat.

2/ Problém s nabíráním LongDateFormat/ ShortDateFormat. Tyto globální proměnné nejsou už v rootu jednotky SysUtils a jsou schovány v záznamu. Zde se musí uvozovat už od verze Delphi XE1

WinLongDateFormat := {$IF CompilerVersion >= 22}FormatSettings{$ELSE}SysUtils{$IFEND}.LongDateFormat;
WinShortDateFormat := {$IF CompilerVersion >= 22}FormatSettings{$ELSE}SysUtils{$IFEND}.ShortDateFormat;

Poznámka:

Při finálním překladu, kdy kód už neobsahoval fatální chyby, se objevila nová fatální chyba před dialogem pro vložení doporučených jednotek (IDE vložilo samo). Chyba se projevila poškozením koncového end v hlavním bloku projektového souboru (zobrazilo se pouze „d.“). Stačí to ručně opravit, ale je to lehce nepříjemné, tato chyba zřejmě přetrvává přes více verzí a nějak patrně souvisí s cache projektu (projektový soubor asi stále nesnáší ruční zásahy).

3/ Finální překlad proběhl se 45 zprávami a 67 varováními. Toto už je slibné a nyní stačí hlášky vyčistit. Hlášky k automatickým konverzím je možné eliminovat např.

type
  ThgMapiErrorMessages = array[1..MAPI_LAST_ERROR_CODE] of string{$IFNDEF UNICODE}[50]{$ENDIF}; 

Pokud se používala konstrukce string50, vždycky to vede po překladu na typ ShortString a ten bude vynucovat automatické konverze (a tím i varování o možných ztrátách). Touto jednoduchou úpravou se hned sníží počet varování o polovinu.

Pak už zůstává jen taková bižuterie jako je záměna Integer za THandle v souborových operacích, CharInSet() pro znakové množiny, případně optimalizace v přetypování, což už je pak na další úvahu.

Pozn. RC: to je důsledek toho, že od XE2 vhledem k 64bit kompilaci byla striktně opravena různá špatná volání, tak aby byla bezpečná i vzhledem k překladu na 64bit

Pro správnost běhu demonstračních programů je zapotřebí upravit formuláře. Zde se přimlouvám za jejich převedení do textového tvaru. Lépe se budou sledovat změny a pak je to text a lze do něj běžnými prostředky sáhnout.

Celkově se mi podařilo stáhnout počet zpráv na polovinu a varování zbylo méně než třetina. To, co ale zbylo, by vyžadovalo pečlivé zamyšlení nad smyslem programového kódu a další případné zásahy, byť kód zdál se být funkčním. Pro tyto účely doporučuji využít buď kódu demonstračních programů, pokud existují a jsou dostatečně obsažné, nebo napsání vlastní testovací jednotky pro ověření nejasných částí kódu.

Zvláštností je, že tato knihovna s sebou nese vlastní verzi DBDemos, a to způsobuje jisté problémy s nastavením databázových prvků jako takových. Ale není to zase takový problém jako celá implementace COM MAPI, která je poplatná době vzniku tj. r. 1997 (a bylo by možná lepší ji celou zahodit :-) ).

Co mě irituje na všech verzích nových Delphi, už snad od verze XE2, je nemožnost jednoduché synchronizace version info. Podařilo se mi dokonce docílit toho, že jsem měl i šest různých version info, které se nějak divně přepisovaly (obzvlášť, když v každé byl zapnut autoinkrement kompilačního čísla), pro debug, release, 32/64bit a i pro všechny. Chybí mi prostě nějaký souborný náhled na všechny nastavené verze, abych si je pěkně srovnal.

Závěr z převodu

Knihovnu, která mi ležela od dob Delphi 3 v šuplíku, se mi podařilo převést do cca jedné hodiny do XE6. Pravda, vím kam sáhnout a co případně poladit, ale v podstatě se stále držím zásad, které Embarcadero radí při převodu non-unicode kódu na poslední verze Delphi.

Doporučuji rozhodně udělat i druhé kolo ladění nad demo aplikacemi, pokud jsou ke knihovně dodané. Pouze překlad balíku nestačí k odhalení různých tikajících bomb, které jsou založeny prostě jenom na tom, že autor pojmenoval nějakou vlastnost stejně jako Embarcadero o deset let později, ale oba každou z nich použili úplně k jinému účelu. A to se jen letmo zmiňuji o různých extra funkcích, které dneska zakrývají jiné, ale bez reintroduce, nebo nelze jinak než funkci přejmenovat (konflikty typu ToText atp.).

Dilatující kód

A malá poznámka skoro na závěr. Někteří programátoři jsou nuceni pracovat v týmech, kde všichni nemají poslední verze Delphi. Pak se požaduje dilatující kód, přeložitelný na více verzích Delphi. Zde je nutné udržovat aktuální společné include v aplikacích, na všech Delphi mít stejné verze knihoven a dodržovat zásady úprav formulářů (formuláře bývají nejčastější příčinou chyb v downgrade). Protože aplikace, ač komplet v unicode, se může v runtime zbořit, když je v DFM něco, co nižší verze neočekává. Řešení je víc, ale asi nejjednodušší je verifikovat DFM na nejnižší možnou verzi Delphi v týmu.

Úvaha na závěr v pár větách

XE6-ka je vyspělý produkt, který vývojáři pomůže, zvlášť když využije schopností CNWizards, balíku expertů a JCL, knihovny pro snazší volání nejen API Windows. Problematičtější se mi zdá zkrácená doba mezi vydáními jednotlivých verzí, předchozí verze se nestačily ani zabydlet (chtělo by se říct „zatvrdnout“) a už tu byla nová verze. Osvojení nové verze trvá většinou déle než půl roku, obzvlášť je-li cíleno na projekt složitější různorodé obchodní aplikace, u které se vyžaduje maximální stabilita a životnost delší než dva roky v aktivním vývoji. …a vůbec, kdo si ještě pamatuje XE4-ku?

Jaro Beneš


Nabízíme Delphi školení na různá témata, primárně ve Vaší firmě.

Tagy:

Recenze

Komentáře

5.5.2014 17:25:33 #

radekc

CnWizard pro XE6 - od verze  CnWizards_1.0.2.668 - http://www.cnpack.org/downbuilds.php?lang=en

radekc

6.5.2014 1:05:48 #

Daniel Andrascik

podla SVN historie sa mi to zda trosku pomylene. V nej totiz XE6 je prvykrat spomenuta az v revizii r1402 a tym padom prvu podporu by prinasala az verzia 1.0.2.669. Ale myslim ze nema zmysel nad tym polemizovat a rovno treba skusat poslednu verziu. I tak podla historie by som este ocakaval vo viacerych "subexpertoch" potencionalnu nekompatibilitu.

Daniel Andrascik

6.5.2014 11:24:06 #

JaroB.

XE6-ka má první hotfix :|
viz
http://cc.embarcadero.com/Item/29847

JaroB.

19.5.2014 14:03:37 #

JaroB.

Je k dispozici nový IDE fix pack pro XE6, viz http://andy.jgknet.de/blog/ide-tools/ide-fix-pack

JaroB.

Komentování ukončeno

Naše nabídka

Partial English version.

MVP
Ing. Radek Červinka - Embarcadero MVP
profil na linkedin, Twitter:@delphicz

Nabízím placené poradenství a konzultace v oblasti programování a vývoje SW.
Dále nabízíme i vývoj speciálního software na zakázku.

Neváhejte nás kontaktovat (i ohledně reklamy nebo burzy práce).

Pokud chcete podpořit tento server libovolnou částkou, můžete použít PayPal. Moc děkuji.

Delphi Certified Developer

O Delphi.cz

Delphi je jediný moderní RAD nástroj podporující tvorbu nativních aplikací pro platformu Win32, Win64 , Mac OSX a na iPhone a Android (s výhledem na další platformy díky FireMonkey) na současném trhu (včetně Windows 8.1).

V současnosti je světová komunita přes dva miliónů vývojářů.

Delphi.cz je nezávislý portál pro uživatele Delphi. Portál není koncipován pro úplné začátečníky, i když i ti se zde nebudou nudit, ale spíše na programátory, kteří již něco znají a chtějí své znalosti dále rozvíjet a sledovat novinky.

Anketa

Poslední komentáře

Comment RSS