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:
procedure TestOld; deprecated 'pouzijte TestNew,
tato procedura v další verzi již nebude';
begin
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:
//system.pas
{The old memory manager structure (for backward compatibility)}
PMemoryManager = ^TMemoryManager;
TMemoryManager = record
GetMem: function(Size: Integer): Pointer;
FreeMem: function(P: Pointer): Integer;
ReallocMem: function(P: Pointer; Size: Integer): Pointer;
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.
function 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
begin
GetSomething;
end.
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
if CheckWin32Version(6,1) then
GetSomething
else
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é