7.4. Создание переносимого кода

На верх  Назад  Вперёд

Free Pascal разработан как кросс-платформенный компилятор. Это означает, что основные модули RTL используются на всех платформах, а поведение компилятора одинаково для всех платформ (насколько это возможно). Язык Object Pascal одинаков для всех платформ. Тем не менее, FPC поставляется с множеством модулей, которые не являются переносимыми, но предоставляют доступ ко всем возможностям, которые имеются в платформе.

Следующие моменты необходимо обдумать при написании переносимого кода:

Старайтесь избегать применения модулей, специфических для какой-либо платформы. Системный модуль, модули объектов и классов, а также модуль SysUtils, гарантируют работу на всех системах. Также как и модуль DOS, но в меньшей степени.

Избегайте использовать прямой доступ к устройствам. Ограниченно доступ к устройствам возможен для большинства платформ при помощи модулей Video, Mouse и Keyboard.

Не используйте трудные для расшифровки соглашения по именам файлов. Подробнее см. ниже.

Учитывайте внутреннее представление типов. Разные процессоры хранят информацию по разному.

Если есть необходимость использовать какие-то специфические системные функции, то лучше выделить эти функции в отдельный модуль. Тогда перенос кода ограничится переопределением данного модуля для другой платформы.

Не используйте ассемблер без особой необходимости, так как у каждого процессора свой набор команд. Некоторые команды не будут работать даже на разных процессорах одного семейства.

Не думайте, что указатели и целые числа имеют одинаковый размер. Это справедливо для 32-битных процессоров Intel, но не обязательно для других процессоров. Тип PtrInt – это псевдоним для целочисленного типа, который имеет одинаковый размер с указателем. Функция SizeInt используется во всех случаях, где необходимо узнать размер.

Системный модуль содержит несколько констант, которые описывают доступ к файловой системе:

Константа

Описание

AllFilesMask

Маска файла, которая возвращает все файлы в каталоге. * -на Unix-подобных платформах, *.* -на DOS и Windows-подобных платформах.

LineEnding

Символ или строка, которые описывают маркер конца строки, используемый на текущей платформе. Обычно это один из #10, #13#10 или #13.

LFNSupport

Логическое значение, которое определяет, поддерживает ли система длинные имена файлов.

DirectorySeparator

Символ, который работает как разделитель между каталогами в имени файла.

DriveSeparator

Для систем, которые поддерживают буквы дисков, это символ, который используется для разделения буквы диска от пути к файлу.

PathSeparator

Символ, используемый для разделения элементов в списке (в особенности PATH).

maxExitCode

Максимальное значение для процесса exitcode.

MaxPathLen

Максимальная длина имени файла, включая путь к файлу.

FileNameCaseSen sitive

Логическое значение, определяющее, нужно ли учитывать регистр при работе с файлами.

UnusedHandle

Значение, используемое для неиспользованного/повреждённого дескриптора файла.

StdInputHandle

Значение дескриптора файла, связанного со стандартным устройством ввода. Не всегда равно 0 (ноль).

StdOutputHandle

Значение дескриптора файла, связанного со стандартным устройством вывода. Не всегда равно 1.

StdErrorHandle

Значение дескриптора файла, связанного со стандартным устройством диагностики вывода. Не всегда равно 2.

CtrlZMarksEOF

Логическое значение, определяющее, нужно ли отмечать символом #26 конец файла (по соглашению на старых MS‑DOS).

Для упрощения написания переносимого кода, файловые процедуры Free Pascal модулей system и sysutils воспринимают разделитель каталогов в пути к файлу одинаково для Windows и Unix, то есть / и \ являются эквивалентными. Это означает, что вы можете использовать символ / в Windows, и он будет трансформирован в обратный слеш (\). И наоборот, в Unix вы можете использовать \.

Этой функцией управляют две предопределённые переменные в системном модуле:

Константа

Описание

AllowDirectorySeparators

Определяет символы, которые используются в именах файлов и обрабатываются как разделители директорий. Они трансформируются в символ DirectorySeparator.

AllowDriveSeparators

Определяет символы, которые используются в именах файлов и обрабатываются как разделители дисков. Они трансформируются в символ DriveSeparator.