Данная глава содержит дополнительные
материалы, которые напрямую не относится к Indy.
20.1. Преобразование Delphi приложений в
Delphi .Net
Данная глава вводит в особенности переноса
существующего кода в DCCIL / Delphi. Net. Она также показывает
элементы, которые больше не применимы и как их обойти, чтобы они
могли правильно работать в .Net framework.
Данная статья так также дает руководство
по оценке преобразования существующего приложения для работы в .Net
framework с помощью DCCIL / Delphi.NET.
20.1.1. Термины
Данная статья сфокусирована на
преобразовании и его последствиях для вашего Delphi кода.
Поэтому, данная статья не является введением в .Net саму по
себе, а только дает определение основных базовых терминов,
относящихся к .NET.
20.1.1.1. CIL
Common Intermediate Language или просто
Intermediate Language (промежуточный язык). Это язык
компилятора, который преобразовывает исходный код, пригодный для
использования в рантайм.
IL выполняет роль, подобную P-коду или
интерпретируемому языку Java. Но также он отличается от них и
реализован совсем иначе.
20.1.1.2. CLR
CLR – это сокращение от Common Language
Runtime. CLR – это основа NET framework и среда исполнения
приложений, которые компилируются в IL. Вначале вам может
показаться, что CLR очень похожа на интерпретатор P-кода,
поскольку выполняет аналогичную роль, но это не интерпретатор
простого P-кода, а много больше.
20.1.1.3. CTS
CTS CLR – это сокращение от Common Type
System. CTS включает предопределенные, базовые .NET типы,
которые доступны в любом .NET языке. Это означает, что integer
больше не определяется каждым компилятором, а встроен в CTS и
поэтому integer полностью одинаков во всех .NET языках.
CTS не ограничен только integer, а
включает много других типов. CTS разделяет типы на две базовые
категории: значения и ссылочные типы.
Типы значений - это типы, которые
записываются в стеке. Вы должны быть знакомы с термином –
простой или порядковый типы. Типы значений включают integers,
bytes и другие примитивы, структуры и перечисления.
Ссылочные типы – это типы, значения
которых сохраняются в куче, и ссылки используются для доступа к
ним. Ссылочные типы включают objects, interfaces и pointers.
20.1.1.4. CLS
CLS – это сокращение от Common Language
Specification. CLS это просто спецификация, которая определяет,
какие свойства языка могут и должны быть поддержаны для работы в
.NET.
20.1.1.5. Управляемый код (Managed Code)
Управляемый код – это код который
компилируется в IL и исполняется с помощью CLR. Основная цель
любого .NET приложения – это быть 100% обслуживаемым кодом. (От
корректора: Ну, блин сказал... ☺)
20.1.1.6. Неуправляемый код (Unmanaged
Code)
Неуправляемый код – это откомпилированный
в машинные инструкции, который получен с помощью Delphi for
Windows. Неуправляемый код также включает код DLL, COM серверов
и даже Win32 API. Основная цель любого .NET приложения – это не
иметь такого кода.
20.1.1.7. Сборка (Assembly)
Сборка это коллекция .NET IL модулей. Это
очень похоже на пакеты в Delphi и Delphi .NET трактует .NET
сборки аналогично пакетам Delphi.
20.1.2. Компиляторы и среды (IDE)
Имеется несколько компиляторов и сред
относящихся к Delphi и к .NET.
20.1.2.1. Компилятор DCCIL (Diesel)
DCCIL – это компилятор командной строки,
который производит .NET вывод. DCCIL – это то, что было названо
как "Delphi .NET preview compiler" и было включено в Delphi 7.
DCC – это имя стандартного компилятора
командной строки в Delphi и это сокращение от Delphi Command
line Compiler.
IL это ссылка на .NET Intermediate
Language.
Отсюда DCC + IL = DCCIL. Произносить
каждый раз D-C-C-I-L слишком громоздко и поэтому было применено
имя "Diesel".
DCCIL имеет подобные DCC параметры и
некоторые специфические для .NET расширения .
20.1.2.1.1 Beta
DCCIL в данный момент находится в
состоянии беты и не рекомендуется для производства коммерческого
кода. Поскольку в нем есть ошибки и даже незаконченные части. Но
нельзя считать его бесполезным и Борланд постоянно выпускает
новые версии.
Поскольку это бета, то она накладывает ограничения на
распространение программ, написанных с помощью DCCIL. Любой код,
который создан с помощью DCCIL, также должен распространяться
как бета.
20.1.2.2. Версия Delphi 8
Borland довольно молчалив по поводу Delphi
8. Тем не менее, опираясь на публичные высказывания мы может
сделать кое какие вывод насчет Delphi 8. Видно, это будет не
Delphi .NET, а расширение для платформы Windows. (От
переводчика: это не подтвердилось.)
20.1.2.3. Проект SideWinder
Так же есть новости о проекте SideWinder
от Борланд. Конечно это не конечное имя, а кодовое имя, которое
Борланд назначил для разработки.
SideWinder так же не Delphi .NET.
SideWinder – это среда разработки C# для .NET, которая, будет
конкурировать с Microsoft Visual Studio .NET.
20.1.2.4. Проект Galileo
Galileo – это кодовое имя Борланд для
повторно используемой среды. Это первый продукт, который
использует SideWinder и Galileo предназначен как базис для
построения среды Delphi .NET, когда она будет выпущена.
20.1.3. Разные среды (Frameworks)
20.1.3.1. Среда .Net Framework
Среда .NET framework – это библиотека
классов, которая является ядром .NET. Данная библиотека классов
включает классы для ввода/вывода, хранения данных, простые типы,
комплексные типы, доступ к базам, пользовательский интерфейс и
многое другое. То чем VCL является для Delphi программистов, тем
же является для .NET программистов.
АПИ Win32 ушло и было заменено классами в
среде .NET, которое предоставляет лучшую и более абстрактную
платформу с независимым интерфейсом. Так же предоставлен и
прямой доступ до Win32 API, и до DLL. Тем не мене использования
подобного доступа делает ваш код не обслуживаемым и
нежелательным в .NET приложениях.
20.1.3.2. Среда WinForms
Среда WinForms – это сборка в .NET
framework, которая включает классы для форм, кнопки, органы
редактирования и другие элементы GUI для построения GUI
приложений. Среда WinForms – это .Net управляемы интерфейс к
Win32 API и – это то, что Visual Studio .NET использует для
построения GUI приложений.
20.1.3.3. Библиотека времени исполнения
RTL
Библиотека времени исполнения RTL содержит
не визуальные низкий уровень классов в Delphi, такие как TList,
TStrings и другие.
Библиотека времени исполнения RTL – также
доступна и в Delphi .NET. Многое из того, что есть в RTL имеет
своих двойников в .NET framework, но предоставив RTL Borland
сделал более простым перенос существующего кода, без
необходимости переписывать большие куски кода и позволяет
создавать кросс платформенный код.
20.1.3.4. Библиотека CLX
Данная часть, вносит некоторый конфуз. До
Delphi 7 было следующее разделение:
• VCL - Visual Component Library. VCL - библиотека визуальных
компонент, что относилось к визуальным компонентам, к не
визуальным компонентам и к RTL.
• CLX (Pronounced "Clicks") - Component Library for Cross
Platform - CLX относилось к новой версии кросс платформенной
части VCL, которая базировалась на QT и могла работать как в
Linux, так и в Windows.
Теперь же, после выхода Delphi 7, Borland
реорганизовал и переопределил значение данного акронима. Это
может привести в большое замешательство, по этому примите во
внимание. Начиная с Delphi 7 новое назначение следующее:
• CLX - CLX относится ко всем компонентам включенным в Delphi,
C++ Builder и в Kylix.
• VCL - VCL относится к визуальным компонентам, которые работают
напрямую с Win32 API.
• Visual CLX - Visual CLX относится к кросс платформенным
визуальным компонентам, которые базируются на QT, доступны и в
Delphi и в Kylix.
• VCL for .NET - VCL for .NET относится к новой VCL, которая
запускается под .NET и предоставляет слой совместимости для
старых приложений и плюс дополнительную функциональность.
Если вы посмотрите на новые определения, я
не уверен, что они согласованы. Я думаю в будущем они приведут к
будущим недоразумениям. Я думаю NLX (Nelix?), или NCL (Nickel?),
или что ни будь еще более more совместимое будет лучшим выбором
для VCL .Net. Как видим, Visual CLX – это подмножество от CLX,
не VCL for .NET – это родной брат VCL, как и Visual CLX.
Это должно выглядеть так:
• VCL --> CLX
• CLX --> Visual CLX
• Visual Parts of VCL --> VCL Хорошо, пусть это все будут мечты.
20.1.3.5. Среда VCL for .Net
Среда VCL for .NET относится к новому VCL,
который работает под .NET и предоставляет уровень совместимости
для старых приложений и добавляет дополнительную
функциональность.
Среда VCL for .NET позволяет сделать более
быстрый перенос существующих приложений, аналогично Win32 VCL и
CLX. Это позволяет продолжать разработку кросс платформенных
приложений. Это важное свойство, которое позволяет продолжать
поддержку Windows приложений без .NET framework и также Linux.
20.1.3.6. Что выбрать WinForms или VCL for
.Net?
Это область для сомнений у пользователей –
должен я использовать WinForms или VCL for .NET для разработки
GUI?
Следующая таблица сравнений позволит вам
сделать правильный выбор. Должны быть установлены жесткие
правила, но каждое приложение должно обслуживаться независимо.


Другая возможность – вы можете смешивать
код. VCL for .NET и WinForms не исключают друг друга и могут
сосуществовать в одном приложении.
20.1.4. Дополнения по переносу
Некоторые из дополнений в Delphi .NET
очень важны для переноса приложений, а некоторые нет. Данные
вещи не являются жизненно важными и поэтому будут рассмотрены
очень кратко.
20.1.4.1. Маппирование типов в CTS
Что бы работать с .NET классами все языки
должны использовать CTS (Common Type System). Delphi .NET может
делать это просто, в дополнение к типам Delphi. Это может иметь
место в ситуации, когда обычный Delphi код использует один набор
типов, а интерфейсы к .NET использует другой набор. В результате
потребуется постоянное копирование данных туда и обратно,
поэтому это не очень хорошая идея с .NET. Подобная ситуация
аналогична ситуацией с COM.
Ел избежание подобной проблемы, родные
типы в Delphi .NET имеют их маппированые типы в CTS. Так что при
объявлении Integer, это в реальности .NET Integer из CTS. Данная
связь не ограничена только простыми типами, но также расширена и
на объекты.
Здесь приведен список некоторых
подстановок:

20.1.4.2. Пространство имен (Namespaces)
Во избежание конфликтов и также как часть
CLS (Common Language Specification), Delphi теперь поддерживает
пространство имен. Каждый модуль теперь существует внутри
пространства имен.
Когда вы видите объявление подобное
следующему:
uses
Borland.Delphi.SysUtils;
var
GStatus: System.Label;
Важно заметить, что VCL for .NET находится
в пространстве имен и влияет на директиву uses.
20.1.4.3. Вложенные типы (Nested Types)
Вложенные типы позволяют объявление типов
внутри другого объявления типа.
20.1.4.4. Пользовательские атрибуты (Custom
Attributes)
.Net не имеет реализации подобной RTTI в
Delphi. Вместо этого она поддерживает нечто подобное, названое
отражение (reflection). Отражение выполняет роль подобную RTTI,
но функционирует немного различно. Reflection зависит от
атрибутов, исполняя некоторые из его функций. Для поддержки
этого Delphi .NET имеет расширение в виде атрибутов.
20.1.4.5. Другие дополнения к языку
Delphi.NET also supports many new smaller
additions to the language such as static class data, record
inheritance, class properties, and more. Most of the
enhancements relate to features of classes at the language level.
While useful and required by the CLS, they
are not essential in porting applications.
20.1.5. Ограничения
Разработка в Delphi .NET требует
использования некоторых ограничений. Эти ограничения требуют,
что бы код Delphi, подчинялся требованиям и ограничениям .NET.
20.1.5.1. Не безопасные элементы
В Delphi 7 появилось новое свойство,
названое "Unsafe". При компилировании вашего кода в Delphi 7, вы
получите предупреждение об не безопасных элементах. Не
безопасные элементы – это такие элементы, которые
непозволительно использовать в .NET рантайм.
Данные предупреждения включены по
умолчанию и серьезно замедляют работу компилятора. Поэтому если
вы не компилируете код для .NET, то вы можете их отключить. Они
производят, то что я назвал эффект "C++ effect". Они замедляют
компиляцию и генерируют большое количество предупреждений, что
приводит к высокому соотношению сигнал-шум".
Delphi 7 может быть использован для
разработки кода, который вы желаете перенести в .NET, но DCCIL
не генерирует предупреждений об небезопасных элементах. Поэтому
первый шаг – это откомпилировать код в Delphi 7 и затем удалить
предупреждения об небезопасных элементах.
Delphi разделяет предупреждения на три
группы – небезопасные типы, небезопасный код и небезопасное
приведение.
20.1.5.1.1 Небезопасные типы Небезопасные
типы включают следующее:
• Символьные указатели: PChar, PWideChar, and PAnsiChar
• Не типизированные указатели
• Не типизированные var и out параметры
• File of <type>
• Real48
• Записи с вариантными частями (Не путайте с variants)
20.1.5.1.2 Небезопасный код
Небезопасный код включает следующее:
• Абсолютные переменные (Absolute)
• Функции Addr(), Ptr(), Hi(), Lo(), Swap()
• Процедуры BlockRead(), and BlockWrite()
• Процедура Fail()
• Процедуры GetMem(), FreeMem(), ReallocMem()
• Ассемблерный код
• Операторы работы с указателями
20.1.5.1.3 Небезопасные приведения (Casts)
Небезопасное приведение включает
следующее:
• Приведение к экземпляру класса, если он не является
наследником
• Любые приведения записей, тип record
20.1.5.2. Откидываемая функциональность (Deprecated
Functionality)
Некоторые элементы были отброшены, так как
они не совместимы с .NET и поэтому бесполезны. Многие из этих
элементов вы уже знаете из ранних глав.
• Тип Real48. используйте BCD или другие
математические функции.
• Функции GetMem(), FreeMem() и ReallocMem(). Используйте
динамические массивы или net управление классами.
• Процедуры BlockRead(), BlockWrite(). Используйте классы из .NET
framework.
• Директива Absolute
• Функции Addr и @. Используйте классы вместо блоков памяти.
• Старые тип объектов Паскаль, ключевое слово object.
Используйте только ключевое слово class.
• TVarData и прямой доступ до потрохов variant. Семантика
Variant поддержана, но только без прямого доступа до
внутренностей.
• File of <type> - размер типов варьируется от платформы к
платформе и не может быть определен во время компилирования и
поэтому не может быть использован.
• Не типизированные var и out параметры. Используйте директиву
const для параметра или класс родителя.
• Указатель PChar. В действительности Delphi .NET поддерживает
PChar как не обслуживаемый код.
• Директивы automated и dispid. Данные директивы неприменимы в .NET.
• Директива asm – ассемблер не поддержан в .NET, код не
компилируется в машинный код.
• TInterfacedObject, который включает AddRef, QueryInterface и
Release.
• Динамические агрегаты – используйте implements. примечание:
Implements не реализовано в текущей версии DCCIL.
• ExitProc
20.1.6. Изменения
Borland инвестировал множество ресурсов в
сохранение совместимости как только это возможно. И Delphi.NET –
это пока еще Delphi, но некоторые вещи не могли быть сохранены
для обратной совместимости.
20.1.6.1. Разрушение (Destruction)
Разрушение в Delphi .NET немного
отличается. Большинство кода не потребует подстройки, но важно
понять в чем же различие.
20.1.6.1.1. Явное разрушение. (Deterministic
Destruction)
В обычном приложении Delphi разрушение
объектов делается явно. Объект разрушается только тогда, когда
код явно вызовет free или destroy. Разрушение может произойти
как часть разрушения собственника, но в конце все равно будет
код по явному вызову free или destroy. Данное поведение
называется как Решительное, явное разрушение.
Явное разрушение позволяет больший
контроль, но склонно к утечкам памяти. Оно также позволяет
делать ошибки, когда на разрушенный объект есть несколько ссылок
или ссылка делается на другую ссылку, а о разрушении неизвестно.
Разрушение требует позаботиться об очистке
объекта (finalization) явным кодом в деструкторе и освобождением
памяти используемой объектом. Поэтому деструктор должен
позаботиться об обеих функциях.
Программисты Delphi часто трактуют эти обе
роли как одну.
20.1.6.1.2. Не явное разрушение
.Net разделяет эти функции – финализации и
освобождения памяти, поскольку памятью заведует .NET. .Net
использует неявное разрушение. Если вы работали с интерфейсами,
то семантика подсчета ссылок, используемая в интерфейсах
аналогична.
Вместо явного разрушения, когда объект сам
разрушается, CLR подсчитывает ссылки на объект. Когда объект
больше не используется, то он помечается для разрушения.
20.1.6.2. Сборка мусора (Garbage
Collection)
.Net использует сборку мусора, что бы
очистить память используемую объектом. Это название процесса,
который определят, что объект больше используется и освобождает
занятую им память.
Сборка мусора .NET очень сложная и даже
базовая информация заслуживает отдельной главы, если даже не
статьи.
Подобно явному и неявному разрушению,
сборка мусора имеет малое влияние на перенос приложения.
Поскольку для процедуры переноса, сборка мусора является ящиком
фокусника, который заботится о разрушении объекта за вас.
20.1.7. Шаги по переносу
Перенос приложений в Delphi .NET для
большинства приложений будет очень значимым и потребует
определенной осторожности. Для большинства
объектно-ориентированного кода, проще чем кажется. Данная статья
не может уменьшить количество работы по переносу, но поможет вам
сделать это легче. Она позволит уменьшить количество ошибок и
предназначена для быстрой реализации переноса.
20.1.7.1. Удаление предупреждений (Unsafe
Warnings)
To remove unsafe warnings, load the target
project into Delphi 7. With the unsafe warnings turned on,
perform a build all. Delphi will produce a series of unsafe
warnings. Each warning needs to be eliminated. This may easily
be the biggest step in porting your application.
20.1.7.2. Модули и пространство имен
Директивы Uses должны быть преобразованы к
использованию пространства имен.
Если код требует одновременного использования в Windows и в .NET
framework данные модули должны использовать IFDEF как указано.
Константа CLR определена в Delphi .NET.
uses
{$IFDEF CLR}Borland.Win32.Windows{$ELSE}Windows{$ENDIF}, {$IFDEF
CLR}Borland.Delphi.SysUtils{$ELSE}SysUtils{$ENDIF}, {$IFDEF CLR}Borland.Vcl.Forms{$ELSE}Forms{$ENDIF};
Пространство имен будет увидено. Три
главных из них – это Borland.Win32 (Windows), Borland.Delphi (RTL)
and Borland.VCL (VCL for .NET).
20.1.7.3. Преобразование DFM
Delphi for .NET пока не поддерживает
формат DFM. Это возможно будет в будущем, так что данный шаг
требуется если вы желаете использовать бета версию DCCIL.
Поскольку DFM не поддержаны, все формы
должны быть сконструированы с помощью кода. Есть также программа
разработанная для выполнения данной задачи, которая может быть
использована с нормальным приложениями Delphi.
20.1.7.4. Преобразование файла проекта
Application.CreateForm более не поддержан,
так что формы должны быть созданы вручную, как обычные
компоненты. Для установки главной формы приложения, установите
свойство Application.MainForm перед вызовом Application.Run.
20.1.7.5. Разрешение с различиями в
классах
Во время компиляции могут проявиться
различия между VCL for .NET и VCL, поскольку появились небольшие
различия между VCL и Visual CLX. Каждое из этих различий должно
быть разрешено с помощью IFDEF.
20.1.7.6. Нужна удача
Если вам повезло, то ваш проект
преобразован и работает нормально.
Перенос – это не только перекомпиляция и
потребует некоторого времени. Перенос в .NET требует подобных
усилий, которые нужны для переноса в из VCL приложений в Visual
CLX. Хотя время и усилия значительны, но это все равно меньше,
чем писать с нуля и позволяет делать кросс платформенную
разработку, так как код будет повторно использоваться и там и
там, конечно если он спланирован должным образом.
20.1.8. Благодарности
Я использовал много источников. Я
извиняюсь, если я кого-то забыл указать в благодарностях. Я
желаю поблагодарить следующих товарищей: John Kaster, Brian Long,
Bob Swart, Lino Tadros, Danny Thorpe, Eddie Churchill, Doychin
Bondzhev.
|