Možná tyto dvě direktivy neznáte - obě dvě jsou totiž relativně nové. Direktiva deprecated byla přidána v Delphi 2009, Direktiva delayed v Delphi 2010.
Direktiva deprecated
Vývoj jde dopředu a Váš kód se musí také vyvíjet. Pokud je ovšem zdrojový kód větší nebo ho někomu dodáváte, je nemožné ze dne na den změnit dané rozhraní do vašeho programu i když víte, že je to v budoucnosti neudržitelné. Takže jednoduše označíte svoje rozhraní jako deprecated tj. zastaralé, a vytvoříte nové.
Programátoři odkázaní na váš výtvor budou schopni kód překládat a bude jim fungovat, ale při kompilaci se jim bude vypisovat hlášení, že tedy do budoucna takto ne a tak jim naznačíte, co je třeba změnit.
Jako deprecated lze označit funkci:
1procedure TestOld; deprecated 'pouzijte TestNew,
2 tato procedura v další verzi již nebude';
3 begin
4
5 end;
vygeneruje toto hlášení
[DCC Warning] Project1.dpr(15): W1000 Symbol 'TestOld' is deprecated:
'pouzijte TestNew, tato procedura v další verzi již nebude'
nebo i např. typ:
1
2
3 PMemoryManager = ^TMemoryManager;
4 TMemoryManager = record
5 GetMem: function(Size: Integer): Pointer;
6 FreeMem: function(P: Pointer): Integer;
7 ReallocMem: function(P: Pointer; Size: Integer): Pointer;
8 end deprecated 'Use TMemoryManagerEx';
Takto je nyní označeno staré rozhraní pro správce paměti (nové přišlo s příchodem FastMM).
Direktiva delayed
PE formát (tj. interní formát pro EXE soubory) obsahuje možnost "pozdní vazby" pro DLL. Zkusím to vysvětlit, i když jsem to jednou nakousl v článku o DLL knihovnách.
Normálně je importovaná DLL knihovna pevně svázána s aplikací, tj. programátor řekne, že funkce A je v DLL knihovne DLL1, takže po startu aplikace je zavedena inkriminovaná knihovna a v ní je nalezena funkce A. Pokud funkce nebo knihovna není nalezena - aplikace havaruje a Game Over.
Toto je samozřejmě problém a navíc může být problémem i to, že se zbytečně zdržuje start hlavního programu zaváděním knihoven, které nejsou ani v ten okamžik potřeba. Po dlouhou dobu bylo jediným řešením to, co jsem napsal v uvedeném článku: dynamicky zjišťovat adresy procedur v knihovně a nějak to pak programově řešit.
Naštěstí Delphi 2010 zavádí inzerovanou direktivu delayed.
1function ExecuteSomething: Integer; external 'coollibrary.dll' delayed;
Tímto bylo řečeno, že při prvním použití funkce ExecuteSomething se RTL pokusí o "propojení", tj. zavedení coollibrary.dll pokud není zavedena, a v ní nalezení funkce ExecuteSomething. Při dalších volání se již použije nalezená funkce.
Pokud nyní napíšeme
1begin
2 GetSomething;
3end.
tak se mohou stát dvě věci:
- pokud je již zavedena jednotka SysUtils bude vyhozena vyjímka
- jinak bude hlášena běhová chyba
To je sice krok kupředu (výjimku lze odchytit), ale pořád uživatel bez dané DLL má smůlu. Pokud ale napíšeme něco jako
1if CheckWin32Version(6,1) then
2 GetSomething
3else
4 EmulateGetSomething;
bude vystaráno. Na patřičné verzi Windows (nebo s patřičnou DLL) se volá pravá funkce, v opačném případě emulujeme její chování (nebo vypíšeme varování), případně zavedeme její alternativu z předchozí verze knihovny (například).
Pokud se nepletu, tak pomocí delayed je implementováno Direct2D a gestures z Delphi 2010.
Pozn.: ale s není zas vhodné to s delayed přehánět, dobrého pomálu - používat jen když to má nějaký smysl.
zdroj: Allen Bauer, Libraries and Packages v Delphi, Delphi Delayed Loading, skoro vyčerpávající zajímavé čtení na JCL blog a na konec Allen Bauer po druhé