Díky komentáři Jaroslava Beneše minule pod článkem (určitě se podívejte na jeho stránky s Delphi drobnostmi - např. TinyDB) jsem se zahloubal do stránek delphibasics.info což jsou opravdu hardcore Delphi programátorské stránky, kde jsem se inspiroval.
Obecně nemám rád honbu za minimální velikostí programu (ale i tak se snažím držet se v rozumných mezích), i když minimální velikostí prázdné aplikace jsem se již věnoval v článku Velikosti EXE u jednotlivých verzí Delphi. Pokud Vás velikost opravdu trápí pro trošku reálnější aplikace, můžete použít KOL jako alternativu k VCL a tím zmenšit velikost aplikace, nebo nahradit System.pas a SysInit.pas za minimální System.pas a SysInit.pas.
Small Applications in Delphi je velmi zajímavý článek se zdrojovými kódy, kdy autor dokázal dostat "hello world" aplikaci s MessageBox v Delphi na cca 980 byte. Skládá se ze dvou částí:
- nahrazení system.pas a sysinit.pas (dva základní soubory RTL) za minimální verze (cca 3.5K)
- nahrazení linkeru delphi za linker od MS (<1K)
Druhý bod mi přijde nefér, ale i tak je 3,5K slušné. Navíc pro implementaci druhého bodu byla nutná speciální technika: kompilátor z Delphi 4 a další, produkuje jiný formát OBJ souborů než očekává MS linker, takže bylo nutné použít neoficiální nástroj OMF2D (k dostání na uvedené stránce), který převede OBJ na kompatibilní formát (může se někomu hodit!).
Musel jsem ale opravit poskytnuté zdrojáky, jinak při ukončování programu Windows 7 64bit zahlásí problém, úprava se týkala _halt0.
unit SysInit;
interface
procedure _InitExe;
procedure _halt0;
procedure _InitLib(Context: PinitContext);
var
ModulelsLib: Boolean;
TlsIndex: Integer = -1;
TlsLast: Byte;
const
PtrToNil: Pointer = nil;
procedure ExitProcess(ExitCode: Integer); stdcall;
external 'kernel32.dll' name 'ExitProcess';
implementation
procedure _InitLib(Context: PinitContext);
asm
end;
procedure _InitExe;
asm
end;
procedure _halt0;
begin
ExitProcess(0);
end;
end.
Není to prima velikost? Zároveň jsem upravil Hello.dpr na
program Hello;
function MessageBoxA(hWnd: Cardinal; lpText, lpCaption: Pchar; uType: Cardinal): Integer;
stdcall; external 'user32.dll' name 'MessageBoxA';
begin
MessageBoxA(0,'Written by n0v4'+#13#10+'www.delphibasics.co.nr','TinyPE in Delphi',0);
end.
Výsledná aplikace byla přeložena D3 kompilátorem (byl v balíku na těch stránkách) na 3584byte. Stejného výsledku jsem dosáhl za použití D5. Za pomocí D2007 se mi překlad už nepodařil (nějak se mi nepodařilo přinutit kompilátor ke kompilaci souboru System.pas).
dcc32.exe -Q system.pas sysinit.pas -M -Y -Z -$D- -0