Уменьшаем размер программ на Делфи

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by begin_end, 22 May 2007.

  1. begin_end

    begin_end

    Joined:
    4 Jan 2007
    Messages:
    254
    Likes Received:
    548
    Reputations:
    470
    Целью данной статьи был обзор и сравнение существующих технологий, средств, методов, позволяющих произвести уменьшения размера программ, написанных на Делфи. К статье прилагаются примеры с исходными кодами и всем необходимым для их компиляции.

    Статья рассчитана на читателей, освоивших работу в Delphi. Некоторые термины, применяемые здесь:
    API – общее наименование для целого набора базовых интерфейсов программирования приложений операционных систем семейства Windows корпорации Майкрософт. Является самым прямым способом взаимодействия приложений с Windows.
    UPX – (the Ultimate Packer for eXecutables) упаковщик исполняемых файлов, поддерживающий несколько различных платформ и форматов файлов. Является открытым программным обеспечением и распространяется по лицензии GNU GPL.
    VCL – (Visual Component Library) библиотека визуальных компонентов, объектно-ориентированная библиотека для разработки программного обеспечения, разработанная компанией «Borland» по принципам визуального программирования.
    KOL – (Key Objects Library) альтернативная VCL библиотека объектных типов для программирования в среде Delphi.

    Создадим простейшее приложение в среде Делфи 7, используя его стандартные средства (VCL). Сделаем форму и на ней надпись “Hello world!” на Label. В опциях проекта отменим использование иконок, инф. о версии. Компилируем и получаем приложение размером 363 Кб. Конечно это многовато. Многие пытаются уменьшить размер, применив «Build with runtime packages», что действительно неплохо работает. Но тут следует учесть, что такой файл программы можно будет запускать только там, где установлен Делфи.

    Не все знают, что вместо VCL можно использовать визуальные компоненты KOL. Та же программа, написанная на KOL, имеет размер всего 24,5 Кб. Почему так и суть технологии можно прочитать здесь .

    Потом перейдём на уровень API, где нам придётся обойтись без технологии WYSIWYG. Начнём с того, что определимся: нам нужна только одна форма и на ней надпись. Это создаётся функциями CreateWindowEx. Естественно нужно организовать и работу с сообщениями (WndProc). Теперь размер программы всего 14 Кб. Но создать многофункциональное приложение так куда тяжелее, чем на KOL.

    В тех 14 Кб ещё довольно много лишнего кода. Чтобы добиться минимума размера приложения на стандартных средствах Делфи придётся отказаться от всех используемых модулей (uses) и даже заменить system.dcu, sysinit.dcu на специальные версии, где всё «лишнее» убрано. Для замены просто положить их в каталог проекта. Но тогда все константы нужно будет обязательно назначить в своём коде, а также вызвать требуемые API-функции из dll. Работа с файлами, строками конечно только на API, потому уже забудем про AssignFile и тип string. Приложение уменьшается до 4 Кб.

    А вот далее, для ещё большего эффекта по размеру, применим технологию от Ms-Rem`a. Что делаем в ходе неё? Сначала получаем obj-файл, компилируя исходник компилятором Делфи (версии 1997 года), и используя почти пустые модули system и sysinit. А после линкуем средством Link.exe (версии 1998 года) и получаем наше приложение на 1,37 Кб. Для этих действий предыдущий исходный код следует несколько изменить – файл проекта сделать файлом модуля (pas), добавив там стартовую процедуру, implementation и проч. Вызывать API из dll тоже по-особому: procedure PostQuitMessage(nExitCode: Integer); stdcall; external user32 name '_PostQuitMessage@4';. Имя функции следует указывать так, как оно записано в соответствующем lib-файле, здесь – USER32.LIB (открываем блокнотом и ищем PostQuitMessage). LIB–файлы брать в комплекте Visual Studio. Обязательно указываем используемые lib в параметрах запуска линкера, которые выглядят, например так: ProjectAPIm.obj user32.lib /ALIGN:32 /incremental:yes /FORCE:UNRESOLVED /SUBSYSTEM:WINDOWS /ENTRY:Start$qqrv /out:projectAPIm.exe. Если хотим включить в приложение ресурсы, то добавляем /pdbtype:sept "FILENAME.RES".

    Компрессия. Все программы, полученные вышеприведенными способами можно упаковать, что, порой значительно снижает размер.

    [​IMG]

    Здесь применялся пакер UPX 1.25. UPX не может сжимать программы win32, которые < 4 Кб. Потому для того, чтобы сжать меньшее приложение пришлось представить его пакеру как приложение DOS. В итоге размер 0,92 Кб, но висит окошко DOS, пока программа запущена, что сильно ограничивает применение метода.

    Для всех описанных способов тут есть готовые примеры от меня. Вы можете модифицировать их в своих целях. Для последнего способа, по Ms-Rem, приложены все нужные средства сборки такого приложения.

    Заключение.
    Данная статья является обзорной, то есть цель не научить, скажем, писать на API, а показать, что это даёт. Для понимания и применения указанных методов нужны определённые навыки программирования на Делфи. Особенно статья поможет тем, кто уже пишет программы на API, но не использует 2 последние методики. Ведь в случае создания, скажем, джоинера важен размер стаба. Стаб пишут на API, но куда лучше написать на API не 14Кб, а 4 или даже 1,4 - изменения уже существующих исходников программы тут потребуются минимальные.
    Прилагающиеся исходные коды можно применять абсолютно свободно. Статью можно дополнять, переопубликовывать, ссылаясь на первоисточник и указывая автора.
     
    _________________________
    #1 begin_end, 22 May 2007
    Last edited: 20 Mar 2008
    4 people like this.
  2. Fen-Omen

    Fen-Omen Elder - Старейшина

    Joined:
    22 Mar 2007
    Messages:
    61
    Likes Received:
    88
    Reputations:
    60
    На Античате такой статьи небыло.....Уже есть, Гуд, так как вопрос по уменьшению размера программ всегда является актуальным...

    А также "готовые примеры" сделанные специально для статьи несомненно являются большим плюсом!
     
    #2 Fen-Omen, 22 May 2007
    Last edited: 22 May 2007
  3. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,204
    Reputations:
    455
    Конечно полезно знать такие вещи для новечков.
    но есть и еще один способ, в продолжении темы.
    После получения минимального приложения, можно его еще раз уменьшить, поковыряясь в MZ header и DOS Stuff.
    Просто Дельфа по дефолту ставит смеешение PE-HEADER'a - 100h = 256 байт от начала файла( так можно снести вообще досовскую часть. И сдвинуть PE-HEADER). На деле можно это чуток укоротить, без явных изменений в проге.
    Дело обстоит тока в том, чтобы подправить значения смещения PE-HEADER и переправить физической смещение секций. И тогда будет вообще прога - меньше не хочу :) Таким методом прогу можно уменишьть еще гдето на 128 байт
     
    #3 slesh, 22 May 2007
    Last edited: 22 May 2007
  4. begin_end

    begin_end

    Joined:
    4 Jan 2007
    Messages:
    254
    Likes Received:
    548
    Reputations:
    470
    Статью просили написать побыстрее, потому я не успел выложить ещё кое-какие данные.
    А именно:

    Результаты компрессии различными exe-пакерами программ, полученных на Делфи по разным технологиям.
    [​IMG]

    Результаты проверки антивирусами каждой из программ, упакованной одним из пакеров, упомянутых в таблице (для проги написанной большей частью на АПИ).

    PS: slesh, молодец!
     
    _________________________
    #4 begin_end, 22 May 2007
    Last edited: 5 Jun 2007
    1 person likes this.
Loading...