Мы исправляли ошибки в VCL в Delphi XE6. Пока что папка содержит:
| VCL Source Fixes
|----- Vcl.ComCtrls.pas
|----- Winapi.CommCtrl.pas
И мы добавляем папку в наш путь поиска Библиотеки:
Попутно мы узнали, что нам нужно ограничить наши исправления implementation
разделом только. В противном случае хеш-сигнатуры символов в разделе interface
изменятся. Это заставляет компоновщик понять, что символы внутри DCU не той версии, которую они ожидают.
Барри Келли дал хорошее объяснение этому поведению:
Важным понятием является концепция версии символа. При сохранении DCU Delphi вычисляет хэш на основе объявления интерфейса символа и связывает его с символом. Другие устройства, использующие этот символ, также сохраняют версию символа. Таким образом избегаются конфликты времени компоновки, вызванные устаревшими символами, в отличие от большинства компоновщиков C.
В результате вы сможете добавить Classes.pas в свой проект и изменить его раздел реализация почти так, как вам нравится, и по-прежнему иметь возможность статически ссылаться с остальными библиотеками RTL и VCL, а также сторонними библиотеками, даже если они представлены только в объектном формате.
Следует остерегаться:
- Встроенные подпрограммы; тело встроенных подпрограмм является частью версии символа
- Дженерики; сторона реализации универсальных типов и методов является частью соответствующих версий символа
Поэтому мы постарались ограничить исправления ошибок разделом реализации (например, введением новых классов взломщиков, а не переопределением метода в общедоступном классе).
А потом
Затем я пошел исправлять в Vcl.Themes.pas
. Я начинаю с простого, копирую файл и помещаю его в папку с исправлениями:
| VCL Source Fixes
|----- Vcl.ComCtrls.pas
|----- Winapi.CommCtrl.pas
|----- Vcl.Themes.pas
Хотя я (еще) даже не модифицировал Vcl.Themes.pas
, компилятор подавился этим:
[dcc32 Fatal Error] Vcl.Themes.pas (2074): F2051 Модуль Vcl.Forms был скомпилирован с другой версией Vcl.Themes.TMouseTrackControlStyleHook
Почему
Важный вопрос:
Почему это происходит?
Что происходит, когда компилятор не может понять, что один и тот же файл является одним и тем же файлом? Возможно ли, что исходный код VCL, поставляемый с XE6, неверен и не соответствует тому, что поставляется в DCU? Это как-то связано с порядком поиска в библиотеке? Имеет ли это какое-то отношение к встраиванию, дженерикам, итераторам, платформам, debug dcus, 64-битному компилятору, ifdefs, автозавершению кода, синергии, нестандартно?
Есть и другие, неявные вопросы, которые связаны с попыткой ответить на почему:
Почему он работает с двумя другими файлами, но не работает с этим?
Почему он не работает, если я даже не изменил файл?
Что ты пробовал?
- пытался перемещать
VCL Source Fixes
вверх и вниз по пути поиска - попытался включить Use debug dcus
- пробовал перейти на 64-битную платформу
- попытался удалить все
dcu
файлы в папке моего проекта (но не удалилD:\Programs\Embarcadero\Studio\14.0\lib\win32\release\Vcl.Themes.dcu
, который поставляется с Delphi XE6) - закрытие XE6 и повторный запуск
- иду к Венди на обед
Конечно хочу исправить. Но больше чем желание исправить это, я хочу понять, почему он не работает. Компилятор не использует магию, вуду или Q-подобные способности. Это детерминированная машина, работающая в соответствии с фиксированным набором (недокументированных) правил.
Почему это происходит?
Ctrl+O+O
, чтобы вставить стандартные параметры компилятора в верхнюю часть заменяемого файла pas. Вот почему я собирался ответить на него здесь: так что у него есть ответ, а не случайные спотыкания в другом месте :) - person Ian Boyd   schedule 29.08.2014