vložil Radek Červinka
11. května 2011 23:09
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.
1unit SysInit;
2
3interface
4procedure _InitExe;
5procedure _halt0;
6procedure _InitLib(Context: PinitContext);
7
8var
9 ModulelsLib: Boolean;
10 TlsIndex: Integer = -1;
11 TlsLast: Byte;
12
13const
14 PtrToNil: Pointer = nil;
15procedure ExitProcess(ExitCode: Integer); stdcall;
16 external 'kernel32.dll' name 'ExitProcess';
17
18
19implementation
20
21procedure _InitLib(Context: PinitContext);
22asm
23end;
24
25procedure _InitExe;
26asm
27end;
28
29procedure _halt0;
30begin
31 ExitProcess(0);
32end;
33
34end.
Není to prima velikost? Zároveň jsem upravil Hello.dpr na
1program Hello;
2function MessageBoxA(hWnd: Cardinal; lpText, lpCaption: Pchar; uType: Cardinal): Integer;
3 stdcall; external 'user32.dll' name 'MessageBoxA';
4begin
5 MessageBoxA(0,'Written by n0v4'+#13#10+'www.delphibasics.co.nr','TinyPE in Delphi',0);
6end.
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