Недавно я начал работать над Delphi и обнаружил, что в оригинальной программе использовалось много пакетов, но я всегда был в невежественном состоянии. Это может занять некоторое время, чтобы изучить эту проблему. Так что сначала перечислите вопросы, которые необходимо проанализировать:
Что такое сумка? Что такое exe? Каковы их композиционные различия? Каковы отношения между пакетом и DCU? Что делает DCP? Каковы отношения между этими файлами во время компиляции? Как это загружено? Как управлять пакетом после загрузки? DLL может экспортировать, но почему Delphi помогает не поднять экспорт пакета, но в пакете используется экспонирование?
Во -первых, давайте посмотрим на процесс компиляции Delphi. В Delphi есть два типа проектов: пакеты и программы. Начните с простого, давайте начнем с DPR. Согласно документации Delphi по справедливости, структура типичного файла DPR заключается в следующем:
1 редактор программы;
2
3 Использование
4 формы, {изменение на Qforms в Linux}
5 reabout в 'reabout.pas' {eablebox},
6 остаться в 'ray.pas' {mainform};
7
8 {$ r *.res}
9
10 Начнется
11 Application.title: = 'Text Editor';
12 Application.CreateForm (tmainform, mainform);
13 Application.Run;
14 конец.
Среди них, от 10 до 14 строк, Begin ... End, естественно, является входом в выполнение программы. Использование детали указывает на некоторые единицы, которые необходимо использовать программе, что довольно расплывчато. нуждаться? Затем каждое устройство будет использовать другие подразделения, и эта проблема, кажется, становится все более сложной. Давайте сначала посмотрим на структуру всего исходного кода:
Я предполагаю, что первый шаг компилятора состоит в том, чтобы пройти через этот направленный график, скомпилировать каждую единицу, если это необходимо, и генерировать соответствующий DCU. Что касается этой «необходимой» вопроса, я изначально думал, что установка использования подразделения, но позже я обнаружил, что это неправильно. Поскольку в приведенном выше случае Unit3 не указывает путь в пункте использования Unit1, но соответствующий файл DCU все еще генерируется правильно. Позже Filemon используется для мониторинга ситуации открытия файла, а процесс обнаружения выглядит следующим образом: Для каждого узла на графике компилятор ищет соответствующие узлы в пути поиска в текущем каталоге - Атрибут проекта - Библиотека в библиотеке Среда, если вы не найдете файл PAS, сделайте это снова, но на этот раз я искал файл DCU, соответствующий узлу.
Теперь, когда компиляция выполнена, каждый блок (то есть файл PAS) сгенерировал файл DCU для него. Когда дело доходит до соединений, проблема сложна. Статическое соединение означает объединение всех этих DCU вместе. Таким образом, призыв одного единицы в другую единицу становится внутренним вопросом программы. Это преимущество заключается в том, что он быстрый и простой, и с такими проблемами, как совместное использование, легко справиться. Недостатком является то, что целевая программа велика, и если сейчас будет записана другая программа, а Unit3 может быть использован повторно, Unit3.dcu будет скопирован снова при подключении. Таким образом, когда две программы работают одновременно, в памяти будет две копии Unit3, которая является пустой тратой. Динамическое соединение означает, что когда две программы подключаются, они сохраняют только ссылки на Unit3 и не копируют контент Unit3. Во время выполнения, загрузите UNIT3 в память и сделайте эти две программы общими. DLL и BPL являются решениями для динамических соединений. Проблема заключается в том, что единственный вариант соединения в Delphi появляется в проекте | Параметры | Меню пакетов, а предложение «сборка с пакетами выполнения» действительно слишком расплывчато. Поэтому нам нужно изучить это снова.
Когда программа выполнена, мы можем использовать представление | Окно отладки | Moudles, чтобы увидеть, какие вещи загружаются в память и какой контент они содержат.
Чтобы быть простым, мы настроили программу со следующей структурой:
Program ProjectExe;
Использование
Формы,
Windows,
Unitformmain в 'UnitformMain.pas' {formMain};
{$ R *.res}
Начинать
Application.initialize;
Application.createform (tformmain, formmain);
Application.Run;
конец.
Unit Formformmain;
интерфейс
Использование
Windows, Stdctrls, формы, Unitformanather, классы, управления;
тип
Tformmain = class (tform)
Баттон1: Tbutton;
процедура Button1click (отправитель: tobject);
Частный
{Частные объявления}
публичный
{Публичные объявления}
конец;
вар
Formmain: tformmain;
Выполнение
{$ R *.dfm}
Процедура tformmain.button1click (отправитель: tobject);
вар
Lform: tformanother;
Начинать
Lform: = tformanother.create (приложение);
Lform.showmodal;
Lform.free;
конец;
конец.
единица единицы форманотера;
интерфейс
Использование
Формы;
тип
Tformanother = class (tform)
Частный
{Частные объявления}
публичный
{Публичные объявления}
конец;
Выполнение
{$ R *.dfm}
конец.
Давайте получим новости сейчас. «Строительница с пакетами времени» проверяется, и теперь обнаружено, что файл ProjectExe.exe. В дереве процессов: RTL60 и VCL60 их содержание - это единицы, которые появились в статическом соединении только сейчас. ProjectExe.exe сейчас всего 16 тыс. Другими словами, часть блока в направленном графике помещается в EXE, а другая часть помещена в BPL. Но на чем основано разделение? Основано на пункте «Использование» или основан на списке в «Build с пакетами времени выполнения»? Продолжая тест, я обнаружил, что если список содержит только VCL60, то два BPL плюс один EXE, загруженный в память, все еще загружаются в память; EXE изменилось: количество единиц внутри увеличилось, и они в основном находятся в пакете VCL60. Я предполагаю, что между пакетами RTL и VCL должны быть требования. Это будет проверено на следующем шаге. Тем не менее, во время начального процесса оценки список пакетов определенно будет использоваться для исключения единиц, которые уже существуют в пакете из EXE.
После динамического соединения есть другая проблема: загрузка. Существует две стратегии для загрузки, статические, также известные как автоматический, который генерирует код от Delphi, и автоматически загружает пакет перед загрузкой EXE; Это память. Проблема в том, что я должен выяснить, при каких обстоятельствах Delphi автоматически загружает пакет, и при каких обстоятельствах я могу избежать умного Delphi, чтобы я мог гибко использовать пакет. В предыдущем эксперименте можно увидеть только до того, как файл DPR будет выполнен для начала, статически подключенный пакет был загружен в память. Я не знаю конкретного процесса.