Глава 7. Компиляция и линковка Ваших программ

Глава  содержит инструкции по компиляции и линковке программ,
написанных на Clipperе. Она состоит из следующих разделов.

* Что выполняет компилятор Clipperа?
* Компиляция программ.
* Функции Clipperа-компоновщика.
* Линковка Ваших программ с использованием линкера фирмы
MS-DOS.
* Линковка программ с использованием линкера PLINK-86 PLUS.
* Пакетные (BAT) файлы.
* Линковка программ с использованием отладчика Clipperа.
* Линковка программ с включением драйверов экрана.
* Линковка программ с функция (FUNC)ми из других библиотек.
* Оверлейные структуры.


а) Если Вы расположите файл компилятора, называемый CLIPPER.EXE,
в какой-либо директории, например в директории с именем CLIPPER,
лучше всего будет включить имя этой директории в опцию команды PATH в
Вашем файле AUTOEXEC.BAT. Это позволит Вам работать с программными
приложениями при их компиляции не вызывая полный путь для поиска
компилятора - файла CLIPPER.EXE. Более подробная информация по среде
DOS Вы можете получить в главе 9.

Во время своей работы компилятор Clipperа преобразовывает
исходный текст программы, написанной на языке DBASE III PLUS, в файл,
содержащий объектный код. Исходный текст программы должен находиться
в файле с расширением ".prg". Для примера, "Example.prg". Объектный код
после Компиляции будет помещен в файл с расширением ".obj". В нашем
случае: "Example.obj".
Объектный файл с помощью линкера может бвть преобразован в
выполняемый файл, имеющий расширение ".exe".
Компилятор Clipperа имеет способность компилировать программы,
процедуры, функции, созданные пользователем и форматные файлы, как
отдельно, так и в группах.
Метод компиляции Вашей программы или группа программ зависит от
того, как Вы структурировали Ваш исходный текст программного
приложения. Вы можете использовать для написания файла с исходным
кодом любой текстовый или строчный редактор. Имеется способность
создавать БД, отчеты и файлы-выборки, используя написанные
программы-приложения, поставляемые с пакетом Clipper.

б) Компиляция Ваших программ.
Для того, чтобы запустить процесс компиляции,
Вы должны набрать следующую команду:

- 208 -
Запуск
компилятора c>Clipper <[d:][\имя директории \]имя файла с>
или путь исходным кодом

Здесь опция:

"Clipper" - вызов самого компилятора Clipperа.

"d:" - буква, идентифицирующая диск, где
размещается файл с исходным текстом.

"имя директории" - описание пути поиска файла с
или путь исходным текстом программы
по дереву директорий, если
это необходимо.

"имя файла" - имя файла, содержащая исходный
текст программ. В данном случае
расширение ".prg" принимается для
файла по умолчанию.

Замечание: Обычно при использовании компилятора
обрабатываемый файл находится в текущей
директории. В этом случае можно не указывать
имя диска и описывать путь поиска файла.

После выполнения эта команда создает в Вашей текущей директории
объектный файл с именем файла типа ".prg", но с расширением ".obj".

Все программы, процедуры и форматные файлы на этапе компиляции,
как отдельные части, в состав объектного файла. Для примера, если
главная клиппер-программа содержит вызов двух подпрограмм, эти подпрограммы
будут включены в состав общего объектного файла.

Замечание: Не включаются синтаксически в состав
объектного файла процедуры и программы,
объявленные в главной программе неявно,
например:

MAIN.PRG - в данном случае
........ компилятор запишет
CLEAR объектный код
DO prog1 программы prog1.prg
........ в состав общего
RETURN объектного файла
......


MAIN.PRG - в этом примере текст
........ программы prog1 должен
CLEAR быть скомпилирован
call_prg="prog1" отдельно и включен в
DO &call_prg состав выполняемого
............ файла на этапе линковки.
RETURN
......


- 209 -
Компилятор в процессе работч стремится обнаружить и записать в
один объектный файл все программы, форматыввода и процедуры, на
которые имеются явные ссылки в тексте основной программы. Поиск
ведется компилятором только в текущем директории. В случае
невозможности обнаружить указанный файл компилер дает сообщение
"cannot open, assumed external" - "невозможно открыть файл, принят
как внешний".
Если Вы используете в качестве инструкции для компилятора файл с
расширением ".clp" (о нем подробнее смотрите главу "Компиляция Ваших
программ с использованием файла типа ".clp") обязательно запишите в
соответствующем порядке имена всех использованных в программе
процедур, форматов ввода и программ в Вашем файле-инструкции для
компилера, имеющего расширение ".clp".
Если Вы не пользуетесь .clp файлом, тогда компиляция
производится в следующем порядке. В первую очередь компилируется Ваш
главный файл с программой и все файлы, содержащие подпрограммы.
Далее, если Clipper встречает в теле программы команду SET PROCEDURE
TO<имя файла - с текстом процедур>, то есть установить (открыть)
такой файл с процедурами, то компилируется файл с заданным именем.
Таким образом, вначале компилер ищет вызываемую процедуру как
отдельный файл, и лишь затем пытается найти ее среди файлов,
перечисленных в опции SET PROCEDURE TO. В случае невозможности
обнаружить процедуры или подпрограммы с таким именем выдается
сообщение "не могу открыть файл, принято как внешний" - "cannot open,
assumed external".

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

Если в процессе компиляции возникают ошибки, связанные с
ошибками, допущенными программистом в исходном тексте программы, то
сообщение о нем выдается на экран. Описание и расшифровка каждого
сообщения приведена в приложении к руководству. Если Вы желаете, Вы
можете воспользоваться возможностями DOS по переназначению
ввода-вывода сообщений компилятора, например в отдельный файл, чтобы
просмотреть или распечатать его позднее. Для примера по команде:
c>Clipper yourprog->erkfile.prg

Все сообщения, выдаваемые компилятором Clipperа, запишатся в
файл с именем erkfile.prg.



При вызове компилятора Clipperа Вы можете
использовать семь различных параметров,
Опции которые указываются в командной строке. Для
компилятора того, чтобы включить некоторые из них или
все, используйте следующий синтаксис написания
строки команды:

c>Clipper <имя файла>[<-l>,<-m>,<-o>,<-p>,<-q>,<-s>,<-t>]

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

Переключатели имеют следующее значение:

- 210 -

Переключатель Значение
------------------------------------------------------------------

-l компиляция без указания номеров строк
* программы

-m компиляция только одного файла, указанного в
опции

-o переместить скомпилированный объектный файл
в указанную директорию

-p компиляция с остановкой для замены диска

-q отменить вывод номеров строк компилируемого
файла на экран

-s включение только проверки синтаксиса написания
команд DBASE III PLUS

-t помещение временного файла на указанный диск

------------------------------------------------------------------



Опция -l исключает указание на номера строк
исходной компилируемой программы из объектного
Компиляция файла. Это позволяет сократить размер
без указания объектного файла на величину 3 байта*число
номеров строк строк программы исходного текста. Однако при
(-l) возникновении ошибки при выполнении программы
не будет указан номер строки, содержащий
ошибку.

Замечание: Если Вы используете (включаете) при линковке
программы отладчик Clipperа, не указывайте
на этапе отладки опцию -l, так как отладчик
использует номера строк программы при своей
работе.



Когда используется данная опция, все
программы и процедуры, вызываемые из
Компиляция компилируемого исходного файла, и не
только описанные в нем, не включаются в выходной
указанного (создаваемый) объектный файл. Эта
файла с способность может быть использована при
исходными внесении изменений только в один из исходных
текстами файлов с текстами программ, с целью
отдельной его компиляции, и без рекомпиляции
остальных текстов исходных программ.




- 211 -
Этот указатель позволяет по завершении процесса
компиляции перемещать объектный файл в любую
Перемещение другую директорию. Используя этот указатель,
объектного нужно проставить в командную строку опцию (-o)
файла (-o) и далее указать путь, куда поместить объектный
файл, например:

c>Clipper example.prg-o c:\clipper\programm

После завершения процесса компиляции объектный файл
Example.obj будет размещен в директории c:\clipper\programm.



При использовании этого переключателя,
Пауза компилятор Clipperа загружается в память и
(-p) ожидает нажатия любой клавишм для начала
выполнения.




Отмена вывода Этот переключатель дает указание компилеру не
на экран выводить на экран номера строк компилируемой
номеров строк программы. Номера строк включаются в объектный
компилируемой файл. Использование данного переключателя
программы (-q) позволяет ускорить скорость компиляции.





Проверка При указании данного переключателя объектный
синтаксиса файл при завершении процесса компиляции не
программы в создается. Ее можно использовать при процессе
исходном выявления ошибок в исходном тексте программы.
тексте (-s)





Перемещение Этот переключатель служит для перенаправления
временного места создания временного файла, создаваемого
файла на компилятором. Для этой цели обычно используется
указанный RAM-диск. Во время процесса компиляции Clipper
диск (-r) создает временный файл с расширением: "$$$".
Для увеличения скорости компиляции создается
временный файл на RAM-диске.

Написание использования данного переключателя следующий:

c>Clipper <имя файла>-t <имя диска, куда помещен временный файл>

При завершении процесса компиляции временный файл удаляется
самим компилятором.


- 212 -




Компиляция Компилятор Clipperа обеспечивает способность
списка компилирования программ с исходным текстом и
программ с групп таких файлов. По группам создается
использованием отдельный объектный файл для каждой группы.
.clp ффйлов

Вообще при написании Ваших программ, процедур, форматов ввода,
функций Вы создаете файлы с текстом программ на языке DBASE, имеющие
расширения ".prg". Достаточно часто программы имеют ссылки (вызывают)
другие файлы типа ".prg". Когда происходит процесс компиляции,
Clipper пытается поместить все файлы типа ".prg", на которые имеются
ссылки, в единый объектный файл.

Может быть несколько причин, по которым выгоднее компилировать
файлы ".prg" по группам в отдельные объектные файлы. Для примера, Вы
можете скомпилировать отдельную группу файлов из всех используемых с
целью отладить какую-нибудь часть программы, или же компилируйте
отдельно процедуры и программы, которые в дальнейшем будут помещены в
оверлейный файл (об использовании и создании оверлеев будет сказано
позднее).
Вот другая причина для компиляции программ списком. При
компилировании Clipper создает две таблицы:

- первая содержит значения констант, использованных в Вашей
программе;

- Вторая содержит использованные символы;

Число констант и символов в таблицах лимитировано. Если в Ваших
клиппер-программах таблица констант содержит более чем 64 Кбайт, то
компилятор сообщит об ошибке с диагностикой: "слишком много
констант". В тоже время, если Вы компилируете Ваши файлы с текстами
программ отдельно с помощью файлов типа ".clp", этой ошибки можно
избежать, разделяя программу на несколько подпрограмм. В дальнейшем
Вы можете использовать линкер для объединения объектных файлов в
выполняемый файл.


Создание Вы можете создать файл типа ".clp", используя
файлов любой редактор или команду DOS "COPY CON".
типа ".clp" Для создаваемого файла необходимо задать
расширение ".clp". Файл этого типа должен
содержать список программ и форматных файлов,
которые Вы хотите откомпилировать. Необходимо
переименовать файлы типа ".fmt" в файлы типа
".prg", если Вы используете компилирование
файла ".clp". Вы можете не указывать расширение
".prg" для файлов с текстами программ. Но
запомните, что ".clp"-файл при его
компилировании не распознает указаний на диски
и директории.

Следующий пример пояснит создание файла типа ".clp" с помощью

- 213 -
команды "COPY CON".

c>COPY CON :Myprog.clp
prog1
prog2
prog3

Затем Ctrl-Z и Enter.

Этот пример приводит к созданию файла типа ".clp", который
содержит имена трех файлов с текстами программ: prog1,prog2,prog3.
Все эти файлы после обработки компилятором файла типа ".clp" будут
скомпилированы отдельно.





Компилирование Для компилирования программ, указанных в файле
файла типа ".clp" типа ".clp", введите следующую команду:

c>Clipper @<имя файла>

где @ является символом-идентификатором для
указания имени файла, где находится клиппер-программа
для раздельной компиляции.

Вышеуказанные команды создают объектный файл с именем, указанным
после @ и с расширением ,obj.




Что делает Изначальное назначение линкера - создание
линкер выполняемых файлов, из одного или более
объектных файлов. Выполняемый файл
запускается через DOS.

Объектные файлыищутся линкером по имени и по расширению типа
".obj". Библиотеки, содержащие функции и команды, находятся в файлах
с расширением ".lib". Выполняемый файл имеет расширение типа ".exe".

Линкер фирмы MICROSOFT(DOS-линкер) используется для создания
EXE-файлов из объектных файлов, если Вы не хотите использовать
оверлейную структуру. Этот линкер значительно быстрее нежели
PLINR-86+.
Однако PLINR-86+ вместе с Clipperом обеспечивает создание
оверлейных структур (про оверлеи будет сказано дальее). Этот метод
разделения Вашего выполняемого файла на отдельные сегменты весьма
полезен, когда его размер превышает допустимый.

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

- 214 -
Для запуска необходимо ввести следующую команду: C>LINK
Далее в коротком диалоге необходимо ввести следующую информацию:
Object Modules[.OBJ]:<имя файла>+<имя файла>+...+<имя файла>
- Загружаются имена объектных файлов. Run File[имя
файла.EXE]:<имя файла>
- Вводится имя исполняемого файла. Если вместо имени ввести
просто Return, то исполняемому файлу будет присвоено то же имя, что и
у объектного. List File[NUL.MAP]:<имя файла>
- Вводится имя листинг-файла (Return - если не нужен).
Libraries[.LIB]:<имя файла>
- Вводятся имена библиотечных файлов (таких, как CLIPPER или
EXTEND). Существует способность ввести всю необходимую информацию из
одной командной строки, например:
C> LINK TEST+PROG1+PROG2,,,\CLIPPER\CLIPPER/se:256
Здесь: TEST,PROG1,PROG2 - объектные файлы.
\CLIPPER\CLIPPER - библиотека Clipperа.

Сборка программ при помощи PLINK86-PLUS.

Существует три способа запуска PLINK86-PLUS: интерактивный, из
командной строки и при помощи .LNK -файла. Во время работы программы
могут возникнуть ошибки. Описание сообщений при возникновении ошибок
приводится в приложении Е. Полный список команд PLINK86-PLUS дан в
приложении I.
Внимание: первый объектный файл, который будет участвовать в
линковке для любого из трех способов запуска, должен быть
скомпилирован Clipperом.
Интерактивный метод.
Для запуска необходимо ввести команду: "PLINK86" и нажать
Return. Линкер загрузится и выдаст приглашение " => ". Теперь можно
ввести команду и нажать Return или ввести несколько команд и нажать
Return. Для завершения сеанса линковки необходимо ввести ";".
Метод командной строки. В этом случае вся информация помещается
в одну строку и запускается нажатием Return. Необходимо
придерживаться следующего синтаксиса:
C>PLINK86 FI<[д:][\путь\]имя файла><,имя файла...><имя файла>
LIB<[д:][\путь\]имя библиотеки>
Исполняемому файлу будет присвоено имя первого объектного файла
в списке. На практике удобно производить линковку в том же
директории, где располагаются скомпилированные Clipperом OBJ-файлы, в
этом случае нет необходимости указывать путь доступа.
.LNK-файл-метод.
В этом случае файл, содержащий полную командную
последовательность или ее часть включается в командную строку с
использованием следующего синтаксиса:
C>PLINK86 @<имя файла>
Здесь <имя файла> - имя файла, содержащего командную
последовательность. По умолчанию ему присваивается расширение .LNK.
.LNK может быть использован в любой точке командной строки и может
иметь до трех уровней вложения, т.е. первый .LNK может иметь ссылку
на второй, который в свою очередь может ссылаться на третий.
Пример:
MYLIST.LNK содержит:
OUTPUT Test.exe
FL Test @Mylist2.lnk

MYLIST2.LNK содержит:

- 215 -
FL Test2
LIB Clipper, Extend

Если запустить линкер строкой:
C> PLINK86 @Mylist
то результат будет такой же, как если бы ввести: OUTPUT Test.exe
FL Test.obj
FL Test2.obj
LIB Clipper, Extend

"OUTPUT" объявляет имя исполняемого файла. Ему автоматически
присваивается расширение .EXE. Если OUTPUT не используется,
исполняемому файлу присваивается имя первого .OBJ-файла.
"FILE" (сокращ. FL) указывает на то, что далее следует имя
объектного файла. Расширение .OBJ здесь указывать необязательно.
"LIBRARY" (сокращ. LIB) указывает имена библиотек.
Использование .LNK-файла в командной строке может быть очень
эффективно. Для примера CL.BAT-файл (см. "Использование файлов пакетной
обработки" позднее в этой главе) может быть модифицирован следующим
образом:
CLIPPER%1
IF NOT ERRORLEVEL 1 PLINK86 FI%1 @C:\CLIPPER\CL.LNK
где: CL.LNK содержит LIB-команду и список библиотек.
Несколько .LNK-файлов может быть включено в одну командную
строку:
C> PLINK86 @Link1 @Link2
.LNK-файлы могут применятся в одной строке вместе с другими
командами линкера, например:
C> PLINK86 @Mylist VERBOSE
Такая строка запускает процесс линковки и вызывает команду
VERBOSE, которая выводит на экран информацию о текущем состоянии
сеанса. Для получения более детальной информации о .LNK-файлах,
следует обратится к обсуждению оверлейных структур позднее в этой
главе. Полное описание команд PLINK86 дано в приложении I.


Работа PLINK86-PLUS

Для запуска на исполнение PLINK86 можно пользоваться любым из
вышеописанных методов, однако при сборке сложных программ с
оверлеями, рекомендуется использовать .LNK.
В случае, если PLINK86 не может найти файлов, определенных в
FILE, LIBRARY или SEARCH, поиск будет продолжен по адресу, указанному
в специальной DOS-изменяемой ".OBJ", которая обычно инициализируется
в AUTOEXEC.BAT. Эта переменная обычно указывает путь в директорий,
содержащий наиболее часто употребляемые библиотеки и объектные файлы.
Для примера, если AUTOEXEC.BAT содержит команду: SET OBJ=\CLIPPER, то
линкер для поиска FILE.OBJ воспользуется доступом
C:\CLIPPER\FILE.OBJ.
В случае успешного окончания сеанса, линкер выдаст нечто
подобное: TEST.EXE (202 K), что означает создание исполняемого файла
с указанным именем и размерами.
Несколько замечаний к вопросу об использовании PLINK86:
- Знак (#) можно испльзовать для указания комментариев в
.LNK-файле.
- Все команды линкера вводятся только в верхнем регистре.
- Если в процессе работы у Вас возникли непреодолимые

- 216 -
затруднения, обращайтесь к Nantucket Support (см. приложение А)

Использование файлов пакетной обработки.
Применение "IF ERRORLEVEL".
Указанная команда позволяет регистрировать наличие ошибки
компиляции при работе Clipperа. Команду удобно использовать в файлах
пакетной обработки перед вызовом линкера:
CLIPPER%1
IF NOT ERRORLEVEL1 LINK %1
,,,\CLIPPER\CLIPPER/se:256 Этот файл поставляется вместе с
CLIPPER-пакетом и служит для автоматической отработки компиляции и
линковки пользовательских программ. Он называется CL.BAT. В пакет
также входит еще один подобный командный файл - CLD.BAT, который
отличается от первого тем, что исполняемая клиппер-программа получает
способность использовать команды Clipper Debugger (подлинковывается
DEBUG.OBJ).
Линковка программ с использованием дополнительных экранных
драйверов. Clipper снабжен несколькими драйверами вывода на экран для
разных модификаций MS-DOS-совместимых машин. Один из них ANSI.OBJ,
предназначенный для терминалов, совместимых по ANSI-стандарту. Чтобы
подключить драйвер к программе, необходимо объявить его на этапе
линковки: C>PLINK86 FILE Test,Ansi.














- 217 -
ОВЕРЛЕИНЫЕ СТРУКТУРЫ В CLIPPERЕ.


До тех пор пока у вас не появилась необходимость в использовании
оверлеев обходитесь без них. Создание и использование оверлеев в
случае , если размер памяти компьютера позволяет обходиться без них,
лишь замедлит выполнение программы. Оверлеи есть смысл применять
тогда когда размер вашей выполняемой программы превышает размер
памяти компьютера. Это препятствие вы можете преодолеть оптимизируя
программу по размеру, увеличивая память инсталированную в компьютер,
но в данном случае более переспективно использовать оверлеи.

ЧТО ТАКОЕ ОВЕРЛЕЙ: Практически оверлей это средство запускать
большие программы используя единовременно меньшие размеры памяти.
Возможен например запуск программы суммарным объемом больше чем вся
память компьютера. Оверлейные программы это части вашей программы
которые не находяться в памяти постоянно , а подгружаются и
выгружаются по мере надобности. Основныя часть программы , называемая
" ядро " постоянно находиться в памяти , а оверлеи находятся на диске
до их вызова. При вызове они загружаются в часть памяти называемую "
зона оверлеев " . Один оверлей замещает при вызове другой как того
требует вызывающая клиппер-программа. После того как оверлей отработал свои
процедуры управление передается вызвавшему " ядру ", а оверлей
остается в памяти, но при вызове следующего оверлея последний
замещает в памяти ранее загруженный. Следующий рисунок иллюстрирует
данное утверждение.
ПАМЯТЬ ДИСК
|---------------------| |--------------------|
| |<----| ОВЕРЛЕЙ 1 |
| ЗОНА | |--------------------|
| ОВЕРЛЕЕВ |<----| ОВЕРЛЕЙ 2 |
| |<--| |--------------------|
|---------------------| |-| ОВЕРЛЕЙ 3 |
| ЯДРО | |--------------------|
| |<----| |
|---------------------| | ЯДРО |
| |
|--------------------|
Если в программе имеется только один оверлей это не приведет к
выиигрышу в памяти, т.к. в памяти помимо размера ядра резидентно
занимается место под один из оверлеев, наибольшего размера.
Для примера для рисунка :

Размер ядра - 160 К
Оверлей 1 - 60 К
Оверлей 2 - 40 К
Оверлей 3 - 30 К

Для загрузки подобной структуры необходимо 220 К памяти , хотя
суммарный объем программы 290 К. Оверлейные куски включаются в
программу на этапе линковки после компиляции . Если вы внесли
изменения в ваш оверлей вам необходимо перелинковать вашу программу.


СТРУКТУРА ОВЕРЛЕЕВ : Пока вы не используете оверлеев все
процедуры вашей программы помещаются в память резидентно при
выполнении и являются доступными из любой процедуры. При
использовании оверлеев лучшим является метод разделения процедур по

- 218 -
функциональному признаку. Это делает оверлейную структуру более
эффективной. Цель при создании оверлея - выделить функционально
независимую часть программы ,которая могла бы выполняться независимо
от других так же обособленных частей. Эта выделенная часть может
содержать любое количество процедур, функций и пр. На рисунке 2 (см
английский вариант) показано логическое и физическое разделение
файлов типа PRG. 11 файлов типа prg компилируются в 6 объектных
файлов. Основная клиппер-программа называемая DB_MAIN осуществляет
поочередный вызов оверлейных кусков , которые не связаны между собой
|---------------------------------|
| |
клиппер-программа -----> объектый модуль ----> оверлей ---->основной
модуль

add1.prg---->|add.obj | ---->|
add2.prg---->| | |
| add_edit.ovl
edit1.prg--->|edit.obj|----->|
edit2.prg--->| | |

report1.prg->|
report2.prg->|rpt.obj |------> rpt.ovl
report3.prg->|

reindex.prg-->reindex.obj---->|
| utility.ovl
backup.prg -->| b_c.obj ----->|
cleanup.prg-->|

db_main.prg ----> db_main.obj--------->db_main.exe


Рисунок 2

КАК СОЗДАТЬ ОВЕРЛЕЙ Оверлеи создаются с помощью PLINK86-Plus в
процессе линковки с использовнием файлов указателей типа .LNK Для
создания структуры определенной на рисунке 2 нужно использовать файл
указателей следующего типа:
FI Db_main
LIB Extend
DEBUG
OVERLAY Prog, $CONSTANTS
BEGINAREA
SECTION FILE Add,Edit
SECTION FILE Rpt
SECTION FILE Reindex,B_c
ENDAREA

Помните ,что линкер автоматически прилинковывает библиотеки
CLIPPER.LIB и OVERLAY.LIB. В процессе линковки происходит разделение
объектных файлов по классам. В зоне данных содержиться описание
стринговых констант и имен переменных. Кодовый сегмент содержит
описание текущих инструкций программы. Clipper обычно помещает
таблицу констант в ядро программы. Опция OVERLAY PROG, $CONSTANTS
используется для помещения данных в зону оверлеев. BEGINAREA
определяет начало зоны оверлеев.ENDAREA конец зоны оверлеев. Все
объектные файлы помещенные между командами BEGINAREA и ENDAREA

- 219 -
автоматически становяться оверлееми.
РАЗМЕЩЕНИЕ ОВЕРЛЕЕВ В ПАМЯТИ При загрузке программы с оверлееми
в память автоматически занимается память под ядро и определяется
размер памяти под оверлейные структуры , принимаемый равным
наибольшему по размеру оверлейному файлу. На рисунке 3 файл
UTILITY.OVL наибольший из трех оверлеев и соответственно размер
необходимой памяти определяется из расчета размер выполняемого файла
плюс размер указанного оверлея. При вызове друго оверлея , меньшего
размера часть памяти остается неиспользованной. Однако необходимо
помнить, что в каждый момент времени в оверлейной зоне может
находиться только один оверлей. Таким образом из оверлея возможен
вызов процедур ядра и самого оверлея, но никак не процедур
определенных в других оверлеев.
ПАМЯТЬ ДИСК
|---------------------| |--------------------|
| |<----| |
| ЗОНА |<--| | |
| ОВЕРЛЕЕВ | | | UTILITY.OVL |
| |<-|| | |
|---------------------| || |--------------------|
| ЯДРО | ||-| RPT.ovl |
| <-|| |--------------------|
|---------------------| ||--| ADD_EDIT.ovl |
| |--------------------|
|---| DB_MAIN.EXE |
| |
|--------------------|


Рисунок 3


ИСПОЛЬЗОВАНИЕ НЕСКОЛЬКИХ ОБЛАСТЕЙ ПОД ОВЕРЛЕИ Ранее
рассматривалась проблема использования одной оверлейной зоны памяти ,
но в принципе можно выделять несколько зон памя ти для загрузки
оверлеев. Для примера вы получите этот результат если немного
модифицируете командный файл для линкера.

BEGINAREA
SECTION FILE ADD,EDIT
SECTION FILE RPT
ENDAREA
BEGINAREA
SECTION FILE REINDEX
SECTION FILE B_C
ENDAREA

В данном случае сформируется следующая структура :


ДИСК ПАМЯТЬ

add_edit.ovl ---------->| overlay area 1
rpt.ovl ---------->|

b_c.ovl ---------->| overlay area 2
reindex.ovl ---------->|

- 220 -

db_main.exe ----------> root area


Рисунок 4

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


ВНЕШНИЕ И ВНУТРЕННИЕ ОВЕРЛЕИ Возможно создание двух типов
оверлеев - внешних и внутренних Функционально они одинаковы , однако
если внутренние оверлеи записаны внутри выполняемого файла, то
внешние размещаются в отдельных файлах снабжаемых расширением .OVL .
Скорость загрузки внутренних оверлеев несколько выше так как не
требует поиска отдельных файлов типа внешних оверлеев на диске.Ондако
используя внешние оверлеи вы можете грузить большие программы с
флоппи дисков или же определить размер каждого оверлея по размеру
файла. Создание внешних оверлеев происходит при помещении в опцию
SECTION ещего указателя INTO. Для примера :
BEGINAREA
SECTION INTO Add_edit.ovl FILE add,edit
SECTION INTO Rpt.ovl FILE Rpt
SECTION INTO Utility.ovl FILE reindex,b_c
ENDAREA


ВЗАИМОВКЛЮЧЕННЫЕ ОВЕРЛЕИ Имеется способность внутри одной
оверлеиной области выделить место для других оверлеев. Однако
использование этой возможности требует внимательного разделения
процедур в программе и хорошего планирования самой структуры
программы. Рисунок 5 иллюстрирует размещение оверлеев подобного типа
в памяти.

ПАМЯТЬ ДИСК ДИСК
----------------
overlay area 1 | | overlay |<------ overlay 4
|<---| area 2 |<------ overlay 5
|<-| | ----------- |
| | | overlay 3 |
|<|| ----------------
root area ||--- overlay 2
|
|---- overlay 1

В следующем примере наша клиппер-программа управления данными
модифицируется следующим образом. Создаются 2 заменяемых оверлея B_C
и REINDEX которые попеременно помещаются в зону выделенную под
объектный файл UTILMENU . Эту же зону памяти использует и файл с
объектным кодом. Создается данная структура по следующим указателям :
BEGINAREA
SECTION INTO Add_edit.ovl FILE add,edit
SECTION INTO Rpt.ovl FILE Rpt
SECTION INTO Utilmenu.ovl FILE Utilmenu
BEGINAREA
SECTION INTO Utilmenu.ovl FILE b_c

- 221 -
SECTION INTO Utilmenu.ovl FILE reindex
ENDAREA
ENDAREA

Подобное размещение оверлеев в памяти может как уменьшать так и
увеличивать необходимый размер памяти. Это зависит от размеров
различных оверлейных кусков. При управлении оверлеями , при их
создании и использовании обязательно помните следующие правила :
- размер памяти для загрузки определяется по наибольшему
оверлею;
- нельзя из оверлея ссылаться на прцедуру в другом оверлее если
они не встроенные;
- используйте мап файл для определения использования памяти
вашей программой с оверлеями.



ОПЦИЯ MAP ЛИНКЕРА PLINK 86 PLUS
--------------------------------

При указании в коммандах к линкеру опции MAP вы получаете
способность иметь карту размещения в памяти всех сегментов вашей
программы.Включение этой возможности производиться командой :
MAP = FILE.MAP S

где, FILE.MAP - имя файла куда помещается карта использования
памяти, а S специальный указатель для подтверждения необходимости
полного отчета.
Если данный указатель не стоит то создается карта-файл типа А
подробно о различных типах смотрите в приложении I.

Используете следующий файл указатель для создания карты :

FI Db_main
LIB Extend
DEBUG
OVERLAY Prog, $CONSTANTS
MAP = Db_main.map S
BEGINAREA
SECTION INTO Add_edit.ovl FILE add,edit
SECTION INTO Rpt.ovl FILE Rpt
SECTION INTO Utility.ovl FILE reindex,b_c
ENDAREA

При указании опции S в мап файл в алфавитном порядке помещаются
все программные сегменты с указанием их адреса на диске , адреса в
памяти и размера. Следующий список служит пояснением к мап файлу.

Название Столбца Содержание

Maddr адрес памяти для загрузки сегмента
Msize размер памяти под секцию
Daddr адрес на диске для сегмента
Dsize размер дисковой памяти под сегмент
Lev Номер уровня для секции резидентно = 0
Ov# Оверлейный номер секции . Не нулевой
номер в этом параметре означает , что

- 222 -
будет сегмент загружаться как оверлей.
Fth Не 0 если сегмент загружен в память
другим оверлеем.
Pload В состоянии "Yes" если произошла
загрузка через оверлейный загрузчик
до выполнения программы.

Вывод всех величин в мап файл производиться в 16-ричном коде.Мап
файлом является обыкновенный текстовый файл, который можно
распечатать.
PLINK86-Plus 2.21
Memory Map for c:DB_MAIN.EXE
Sections
Name Maddr Msize Daddr Dsize Lev Ov# Fth Pload

root 0 23370 2200 23370 0 0 0 no
add_edit 23370 ab60 60 ab60 1 1 0 no
rpt 23370 e9c0 60 e9c0 1 2 0 no
utility 23370 f670 c0 f670 1 3 0 no
329e0 a2f0 26680 a2f0 0 4 0 Yes

Просмотрев директорию диска после линковки можно определить
размер оверлейных файлов.
Директория C:\db

add_edit.ovl 43968
rpt.ovl 59936
utility.ovl 63280

Переведем значения из 16-ричной в 10-ную и получим абсолютные
значения в байтах для каждого программного сегмента :

16-ричный 10-чный
60 96
с0 192
AB60 43840
E9C0 59840
F670 63088

Cложив значения Daddr и Dsize получим значение для файла в
директории

Файл Daddr + Dsize Всего

add_edit 96 43872 43968
rpt 96 59840 59936
utility 192 63088 63280
Оверлейные файлы исходя из размера наибольшего из них
размещается по следующим 16-ричным адресам от 23370 до адреса со
смещением F670 или же в десятичной системе 63088 байт.


ПРИМЕР МАР ФАЙЛА ДЛЯ ВЛОЖЕННОЙ ОВЕРЛЕЙНОЙ СТРУКТУРЫ Отладчик
имеющийся в пакете позволяет протестировать и отладить оверлейные
куски при их загрузке в память и выполнении. Последовательность
загрузки оверлеев и их вложенность определяется как
последовательность комманд в файле указателей для линкера. При

- 223 -
использовании отладчика есть способность разложить процесс загрузки
оверлеев по шагам. В мар файле в опции Ov# указывается очередность
размещения оверлеев. Заметьте , что нижеприведенный мар файл
относиться к вложенной оверлейной структуре.
PLINK86-Plus 2.21
Memory Map for c:DB_MAIN.EXE
Sections
Name Maddr Msize Daddr Dsize Lev Ov# Fth Pload

root 0 23370 2200 23370 0 0 0 no
add_edit 23370 ab60 60 ab60 1 1 0 no
rpt 23370 e9c0 60 e9c0 1 2 0 no
utilmenu 23370 459 e0 459 1 3 0 no
reindex 237c9 7528 539 7528 2 4 3 no
b_c 237c9 8238 7a61 8238 2 5 3 no
329e0 a2f0 26680 a2f0 0 4 0 Yes

Вложенные оверлеи по мар файлу можно выделить по опции lev для
них здесь указано 2 - т.е. второй уровень вложенности. В опции Fth
определ
UTILMENU.
Помните что ядро программы постоянно находиться в памяти , а
каждый оверлейный кусок загружаясь в память в свою очередь и
производя вызов в свою область памяти своего вложенного оверлея ,
остается в памяти сам. То есть при вызове вложенного оверлея он не
замещает оверлей предок в памяти. Резидентный кусок обозначен в файле
в опции Lev значением 0. Это значение изменяется при включении внутри
оверлея новых вложенных овердлеев и находиться в интервале от 0 до 31
,так как в clipperе возможно до 32 уровней

Глава 7. Компиляция и линковка Ваших программ
------------------------------------


Глава 7 содержит инструкции по компиляции и линковке программ,
написанных на Clipperе. Она состоит из следующих разделов.

* Что выполняет компилятор Clipperа?

* Компиляция программ.

* Функции Clipperа-компоновщика.

* Линковка Ваших программ с использованием линкера фирмы
MS-DOS.

* Линковка программ с использованием линкера PLINK-86 PLUS.

* Пакетные (BAT) файлы.

* Линковка программ с использованием отладчика Clipperа.

* Линковка программ с включением драйверов экрана.

* Линковка программ с функция (FUNC)ми из других библиотек.

* Оверлейные структуры.


а) Если Вы расположите файл компилятора, называемый CLIPPER.EXE,
в какой-либо директории, например в директории с именем CLIPPER,
лучше всего будет включить имя этой директории в опцию команды PATH в
Вашем файле AUTOEXEC.BAT. Это позволит Вам работать с программными
приложениями при их компиляции не вызывая полный путь для поиска
компилятора - файла CLIPPER.EXE. Более подробная информация по среде
DOS Вы можете получить в главе 9.

Во время своей работы компилятор Clipperа преобразовывает
исходный текст программы, написанной на языке DBASE III PLUS, в файл,
содержащий объектный код. Исходный текст программы должен находиться
в файле с расширением ".prg". Для примера, "Example.prg". Объектный код
после Компиляции будет помещен в файл с расширением ".obj". В нашем
случае: "Example.obj".
Объектный файл с помощью линкера может бвть преобразован в
выполняемый файл, имеющий расширение ".exe".
Компилятор Clipperа имеет способность компилировать программы,
процедуры, функции, созданные пользователем и форматные файлы, как
отдельно, так и в группах.
Метод компиляции Вашей программы или группа программ зависит от
того, как Вы структурировали Ваш исходный текст программного
приложения. Вы можете использовать для написания файла с исходным
кодом любой текстовый или строчный редактор. Имеется способность
создавать БД, отчеты и файлы-выборки, используя написанные
программы-приложения, поставляемые с пакетом Clipper.

б) Компиляция Ваших программ.
Для того, чтобы запустить процесс компиляции,
Вы должны набрать следующую команду:

- 208 -
Запуск
компилятора c>Clipper <[d:][\имя директории \]имя файла с>
или путь исходным кодом

Здесь опция:

"Clipper" - вызов самого компилятора Clipperа.

"d:" - буква, идентифицирующая диск, где
размещается файл с исходным текстом.

"имя директории" - описание пути поиска файла с
или путь исходным текстом программы
по дереву директорий, если
это необходимо.

"имя файла" - имя файла, содержащая исходный
текст программ. В данном случае
расширение ".prg" принимается для
файла по умолчанию.

Замечание: Обычно при использовании компилятора
обрабатываемый файл находится в текущей
директории. В этом случае можно не указывать
имя диска и описывать путь поиска файла.

После выполнения эта команда создает в Вашей текущей директории
объектный файл с именем файла типа ".prg", но с расширением ".obj".

Все программы, процедуры и форматные файлы на этапе компиляции,
как отдельные части, в состав объектного файла. Для примера, если
главная клиппер-программа содержит вызов двух подпрограмм, эти подпрограммы
будут включены в состав общего объектного файла.

Замечание: Не включаются синтаксически в состав
объектного файла процедуры и программы,
объявленные в главной программе неявно,
например:

MAIN.PRG - в данном случае
........ компилятор запишет
CLEAR объектный код
DO prog1 программы prog1.prg
........ в состав общего
RETURN объектного файла
......


MAIN.PRG - в этом примере текст
........ программы prog1 должен
CLEAR быть скомпилирован
call_prg="prog1" отдельно и включен в
DO &call_prg состав выполняемого
............ файла на этапе линковки.
RETURN
......


- 209 -
Компилятор в процессе работч стремится обнаружить и записать в
один объектный файл все программы, форматыввода и процедуры, на
которые имеются явные ссылки в тексте основной программы. Поиск
ведется компилятором только в текущем директории. В случае
невозможности обнаружить указанный файл компилер дает сообщение
"cannot open, assumed external" - "невозможно открыть файл, принят
как внешний".
Если Вы используете в качестве инструкции для компилятора файл с
расширением ".clp" (о нем подробнее смотрите главу "Компиляция Ваших
программ с использованием файла типа ".clp") обязательно запишите в
соответствующем порядке имена всех использованных в программе
процедур, форматов ввода и программ в Вашем файле-инструкции для
компилера, имеющего расширение ".clp".
Если Вы не пользуетесь .clp файлом, тогда компиляция
производится в следующем порядке. В первую очередь компилируется Ваш
главный файл с программой и все файлы, содержащие подпрограммы.
Далее, если Clipper встречает в теле программы команду SET PROCEDURE
TO<имя файла - с текстом процедур>, то есть установить (открыть)
такой файл с процедурами, то компилируется файл с заданным именем.
Таким образом, вначале компилер ищет вызываемую процедуру как
отдельный файл, и лишь затем пытается найти ее среди файлов,
перечисленных в опции SET PROCEDURE TO. В случае невозможности
обнаружить процедуры или подпрограммы с таким именем выдается
сообщение "не могу открыть файл, принято как внешний" - "cannot open,
assumed external".

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

Если в процессе компиляции возникают ошибки, связанные с
ошибками, допущенными программистом в исходном тексте программы, то
сообщение о нем выдается на экран. Описание и расшифровка каждого
сообщения приведена в приложении к руководству. Если Вы желаете, Вы
можете воспользоваться возможностями DOS по переназначению
ввода-вывода сообщений компилятора, например в отдельный файл, чтобы
просмотреть или распечатать его позднее. Для примера по команде:
c>Clipper yourprog->erkfile.prg

Все сообщения, выдаваемые компилятором Clipperа, запишатся в
файл с именем erkfile.prg.



При вызове компилятора Clipperа Вы можете
использовать семь различных параметров,
Опции которые указываются в командной строке. Для
компилятора того, чтобы включить некоторые из них или
все, используйте следующий синтаксис написания
строки команды:

c>Clipper <имя файла>[<-l>,<-m>,<-o>,<-p>,<-q>,<-s>,<-t>]

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

Переключатели имеют следующее значение:

- 210 -

Переключатель Значение
------------------------------------------------------------------

-l компиляция без указания номеров строк
* программы

-m компиляция только одного файла, указанного в
опции

-o переместить скомпилированный объектный файл
в указанную директорию

-p компиляция с остановкой для замены диска

-q отменить вывод номеров строк компилируемого
файла на экран

-s включение только проверки синтаксиса написания
команд DBASE III PLUS

-t помещение временного файла на указанный диск

------------------------------------------------------------------



Опция -l исключает указание на номера строк
исходной компилируемой программы из объектного
Компиляция файла. Это позволяет сократить размер
без указания объектного файла на величину 3 байта*число
номеров строк строк программы исходного текста. Однако при
(-l) возникновении ошибки при выполнении программы
не будет указан номер строки, содержащий
ошибку.

Замечание: Если Вы используете (включаете) при линковке
программы отладчик Clipperа, не указывайте
на этапе отладки опцию -l, так как отладчик
использует номера строк программы при своей
работе.



Когда используется данная опция, все
программы и процедуры, вызываемые из
Компиляция компилируемого исходного файла, и не
только описанные в нем, не включаются в выходной
указанного (создаваемый) объектный файл. Эта
файла с способность может быть использована при
исходными внесении изменений только в один из исходных
текстами файлов с текстами программ, с целью
отдельной его компиляции, и без рекомпиляции
остальных текстов исходных программ.




- 211 -
Этот указатель позволяет по завершении процесса
компиляции перемещать объектный файл в любую
Перемещение другую директорию. Используя этот указатель,
объектного нужно проставить в командную строку опцию (-o)
файла (-o) и далее указать путь, куда поместить объектный
файл, например:

c>Clipper example.prg-o c:\clipper\programm

После завершения процесса компиляции объектный файл
Example.obj будет размещен в директории c:\clipper\programm.



При использовании этого переключателя,
Пауза компилятор Clipperа загружается в память и
(-p) ожидает нажатия любой клавишм для начала
выполнения.




Отмена вывода Этот переключатель дает указание компилеру не
на экран выводить на экран номера строк компилируемой
номеров строк программы. Номера строк включаются в объектный
компилируемой файл. Использование данного переключателя
программы (-q) позволяет ускорить скорость компиляции.





Проверка При указании данного переключателя объектный
синтаксиса файл при завершении процесса компиляции не
программы в создается. Ее можно использовать при процессе
исходном выявления ошибок в исходном тексте программы.
тексте (-s)





Перемещение Этот переключатель служит для перенаправления
временного места создания временного файла, создаваемого
файла на компилятором. Для этой цели обычно используется
указанный RAM-диск. Во время процесса компиляции Clipper
диск (-r) создает временный файл с расширением: "$$$".
Для увеличения скорости компиляции создается
временный файл на RAM-диске.

Написание использования данного переключателя следующий:

c>Clipper <имя файла>-t <имя диска, куда помещен временный файл>

При завершении процесса компиляции временный файл удаляется
самим компилятором.


- 212 -




Компиляция Компилятор Clipperа обеспечивает способность
списка компилирования программ с исходным текстом и
программ с групп таких файлов. По группам создается
использованием отдельный объектный файл для каждой группы.
.clp ффйлов

Вообще при написании Ваших программ, процедур, форматов ввода,
функций Вы создаете файлы с текстом программ на языке DBASE, имеющие
расширения ".prg". Достаточно часто программы имеют ссылки (вызывают)
другие файлы типа ".prg". Когда происходит процесс компиляции,
Clipper пытается поместить все файлы типа ".prg", на которые имеются
ссылки, в единый объектный файл.

Может быть несколько причин, по которым выгоднее компилировать
файлы ".prg" по группам в отдельные объектные файлы. Для примера, Вы
можете скомпилировать отдельную группу файлов из всех используемых с
целью отладить какую-нибудь часть программы, или же компилируйте
отдельно процедуры и программы, которые в дальнейшем будут помещены в
оверлейный файл (об использовании и создании оверлеев будет сказано
позднее).
Вот другая причина для компиляции программ списком. При
компилировании Clipper создает две таблицы:

- первая содержит значения констант, использованных в Вашей
программе;

- Вторая содержит использованные символы;

Число констант и символов в таблицах лимитировано. Если в Ваших
клиппер-программах таблица констант содержит более чем 64 Кбайт, то
компилятор сообщит об ошибке с диагностикой: "слишком много
констант". В тоже время, если Вы компилируете Ваши файлы с текстами
программ отдельно с помощью файлов типа ".clp", этой ошибки можно
избежать, разделяя программу на несколько подпрограмм. В дальнейшем
Вы можете использовать линкер для объединения объектных файлов в
выполняемый файл.


Создание Вы можете создать файл типа ".clp", используя
файлов любой редактор или команду DOS "COPY CON".
типа ".clp" Для создаваемого файла необходимо задать
расширение ".clp". Файл этого типа должен
содержать список программ и форматных файлов,
которые Вы хотите откомпилировать. Необходимо
переименовать файлы типа ".fmt" в файлы типа
".prg", если Вы используете компилирование
файла ".clp". Вы можете не указывать расширение
".prg" для файлов с текстами программ. Но
запомните, что ".clp"-файл при его
компилировании не распознает указаний на диски
и директории.

Следующий пример пояснит создание файла типа ".clp" с помощью

- 213 -
команды "COPY CON".

c>COPY CON :Myprog.clp
prog1
prog2
prog3

Затем Ctrl-Z и Enter.

Этот пример приводит к созданию файла типа ".clp", который
содержит имена трех файлов с текстами программ: prog1,prog2,prog3.
Все эти файлы после обработки компилятором файла типа ".clp" будут
скомпилированы отдельно.





Компилирование Для компилирования программ, указанных в файле
файла типа ".clp" типа ".clp", введите следующую команду:

c>Clipper @<имя файла>

где @ является символом-идентификатором для
указания имени файла, где находится клиппер-программа
для раздельной компиляции.

Вышеуказанные команды создают объектный файл с именем, указанным
после @ и с расширением ,obj.




Что делает Изначальное назначение линкера - создание
линкер выполняемых файлов, из одного или более
объектных файлов. Выполняемый файл
запускается через DOS.

Объектные файлыищутся линкером по имени и по расширению типа
".obj". Библиотеки, содержащие функции и команды, находятся в файлах
с расширением ".lib". Выполняемый файл имеет расширение типа ".exe".

Линкер фирмы MICROSOFT(DOS-линкер) используется для создания
EXE-файлов из объектных файлов, если Вы не хотите использовать
оверлейную структуру. Этот линкер значительно быстрее нежели
PLINR-86+.
Однако PLINR-86+ вместе с Clipperом обеспечивает создание
оверлейных структур (про оверлеи будет сказано дальее). Этот метод
разделения Вашего выполняемого файла на отдельные сегменты весьма
полезен, когда его размер превышает допустимый.

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

- 214 -
Для запуска необходимо ввести следующую команду: C>LINK
Далее в коротком диалоге необходимо ввести следующую информацию:
Object Modules[.OBJ]:<имя файла>+<имя файла>+...+<имя файла>
- Загружаются имена объектных файлов. Run File[имя
файла.EXE]:<имя файла>
- Вводится имя исполняемого файла. Если вместо имени ввести
просто Return, то исполняемому файлу будет присвоено то же имя, что и
у объектного. List File[NUL.MAP]:<имя файла>
- Вводится имя листинг-файла (Return - если не нужен).
Libraries[.LIB]:<имя файла>
- Вводятся имена библиотечных файлов (таких, как CLIPPER или
EXTEND). Существует способность ввести всю необходимую информацию из
одной командной строки, например:
C> LINK TEST+PROG1+PROG2,,,\CLIPPER\CLIPPER/se:256
Здесь: TEST,PROG1,PROG2 - объектные файлы.
\CLIPPER\CLIPPER - библиотека Clipperа.

Сборка программ при помощи PLINK86-PLUS.

Существует три способа запуска PLINK86-PLUS: интерактивный, из
командной строки и при помощи .LNK -файла. Во время работы программы
могут возникнуть ошибки. Описание сообщений при возникновении ошибок
приводится в приложении Е. Полный список команд PLINK86-PLUS дан в
приложении I.
Внимание: первый объектный файл, который будет участвовать в
линковке для любого из трех способов запуска, должен быть
скомпилирован Clipperом.
Интерактивный метод.
Для запуска необходимо ввести команду: "PLINK86" и нажать
Return. Линкер загрузится и выдаст приглашение " => ". Теперь можно
ввести команду и нажать Return или ввести несколько команд и нажать
Return. Для завершения сеанса линковки необходимо ввести ";".
Метод командной строки. В этом случае вся информация помещается
в одну строку и запускается нажатием Return. Необходимо
придерживаться следующего синтаксиса:
C>PLINK86 FI<[д:][\путь\]имя файла><,имя файла...><имя файла>
LIB<[д:][\путь\]имя библиотеки>
Исполняемому файлу будет присвоено имя первого объектного файла
в списке. На практике удобно производить линковку в том же
директории, где располагаются скомпилированные Clipperом OBJ-файлы, в
этом случае нет необходимости указывать путь доступа.
.LNK-файл-метод.
В этом случае файл, содержащий полную командную
последовательность или ее часть включается в командную строку с
использованием следующего синтаксиса:
C>PLINK86 @<имя файла>
Здесь <имя файла> - имя файла, содержащего командную
последовательность. По умолчанию ему присваивается расширение .LNK.
.LNK может быть использован в любой точке командной строки и может
иметь до трех уровней вложения, т.е. первый .LNK может иметь ссылку
на второй, который в свою очередь может ссылаться на третий.
Пример:
MYLIST.LNK содержит:
OUTPUT Test.exe
FL Test @Mylist2.lnk

MYLIST2.LNK содержит:

- 215 -
FL Test2
LIB Clipper, Extend

Если запустить линкер строкой:
C> PLINK86 @Mylist
то результат будет такой же, как если бы ввести: OUTPUT Test.exe
FL Test.obj
FL Test2.obj
LIB Clipper, Extend

"OUTPUT" объявляет имя исполняемого файла. Ему автоматически
присваивается расширение .EXE. Если OUTPUT не используется,
исполняемому файлу присваивается имя первого .OBJ-файла.
"FILE" (сокращ. FL) указывает на то, что далее следует имя
объектного файла. Расширение .OBJ здесь указывать необязательно.
"LIBRARY" (сокращ. LIB) указывает имена библиотек.
Использование .LNK-файла в командной строке может быть очень
эффективно. Для примера CL.BAT-файл (см. "Использование файлов пакетной
обработки" позднее в этой главе) может быть модифицирован следующим
образом:
CLIPPER%1
IF NOT ERRORLEVEL 1 PLINK86 FI%1 @C:\CLIPPER\CL.LNK
где: CL.LNK содержит LIB-команду и список библиотек.
Несколько .LNK-файлов может быть включено в одну командную
строку:
C> PLINK86 @Link1 @Link2
.LNK-файлы могут применятся в одной строке вместе с другими
командами линкера, например:
C> PLINK86 @Mylist VERBOSE
Такая строка запускает процесс линковки и вызывает команду
VERBOSE, которая выводит на экран информацию о текущем состоянии
сеанса. Для получения более детальной информации о .LNK-файлах,
следует обратится к обсуждению оверлейных структур позднее в этой
главе. Полное описание команд PLINK86 дано в приложении I.


Работа PLINK86-PLUS

Для запуска на исполнение PLINK86 можно пользоваться любым из
вышеописанных методов, однако при сборке сложных программ с
оверлеями, рекомендуется использовать .LNK.
В случае, если PLINK86 не может найти файлов, определенных в
FILE, LIBRARY или SEARCH, поиск будет продолжен по адресу, указанному
в специальной DOS-изменяемой ".OBJ", которая обычно инициализируется
в AUTOEXEC.BAT. Эта переменная обычно указывает путь в директорий,
содержащий наиболее часто употребляемые библиотеки и объектные файлы.
Для примера, если AUTOEXEC.BAT содержит команду: SET OBJ=\CLIPPER, то
линкер для поиска FILE.OBJ воспользуется доступом
C:\CLIPPER\FILE.OBJ.
В случае успешного окончания сеанса, линкер выдаст нечто
подобное: TEST.EXE (202 K), что означает создание исполняемого файла
с указанным именем и размерами.
Несколько замечаний к вопросу об использовании PLINK86:
- Знак (#) можно испльзовать для указания комментариев в
.LNK-файле.
- Все команды линкера вводятся только в верхнем регистре.
- Если в процессе работы у Вас возникли непреодолимые

- 216 -
затруднения, обращайтесь к Nantucket Support (см. приложение А)

Использование файлов пакетной обработки.
Применение "IF ERRORLEVEL".
Указанная команда позволяет регистрировать наличие ошибки
компиляции при работе Clipperа. Команду удобно использовать в файлах
пакетной обработки перед вызовом линкера:
CLIPPER%1
IF NOT ERRORLEVEL1 LINK %1
,,,\CLIPPER\CLIPPER/se:256 Этот файл поставляется вместе с
CLIPPER-пакетом и служит для автоматической отработки компиляции и
линковки пользовательских программ. Он называется CL.BAT. В пакет
также входит еще один подобный командный файл - CLD.BAT, который
отличается от первого тем, что исполняемая клиппер-программа получает
способность использовать команды Clipper Debugger (подлинковывается
DEBUG.OBJ).
Линковка программ с использованием дополнительных экранных
драйверов. Clipper снабжен несколькими драйверами вывода на экран для
разных модификаций MS-DOS-совместимых машин. Один из них ANSI.OBJ,
предназначенный для терминалов, совместимых по ANSI-стандарту. Чтобы
подключить драйвер к программе, необходимо объявить его на этапе
линковки: C>PLINK86 FILE Test,Ansi.














- 217 -
ОВЕРЛЕИНЫЕ СТРУКТУРЫ В CLIPPERЕ.


До тех пор пока у вас не появилась необходимость в использовании
оверлеев обходитесь без них. Создание и использование оверлеев в
случае , если размер памяти компьютера позволяет обходиться без них,
лишь замедлит выполнение программы. Оверлеи есть смысл применять
тогда когда размер вашей выполняемой программы превышает размер
памяти компьютера. Это препятствие вы можете преодолеть оптимизируя
программу по размеру, увеличивая память инсталированную в компьютер,
но в данном случае более переспективно использовать оверлеи.

ЧТО ТАКОЕ ОВЕРЛЕЙ: Практически оверлей это средство запускать
большие программы используя единовременно меньшие размеры памяти.
Возможен например запуск программы суммарным объемом больше чем вся
память компьютера. Оверлейные программы это части вашей программы
которые не находяться в памяти постоянно , а подгружаются и
выгружаются по мере надобности. Основныя часть программы , называемая
" ядро " постоянно находиться в памяти , а оверлеи находятся на диске
до их вызова. При вызове они загружаются в часть памяти называемую "
зона оверлеев " . Один оверлей замещает при вызове другой как того
требует вызывающая клиппер-программа. После того как оверлей отработал свои
процедуры управление передается вызвавшему " ядру ", а оверлей
остается в памяти, но при вызове следующего оверлея последний
замещает в памяти ранее загруженный. Следующий рисунок иллюстрирует
данное утверждение.
ПАМЯТЬ ДИСК
|---------------------| |--------------------|
| |<----| ОВЕРЛЕЙ 1 |
| ЗОНА | |--------------------|
| ОВЕРЛЕЕВ |<----| ОВЕРЛЕЙ 2 |
| |<--| |--------------------|
|---------------------| |-| ОВЕРЛЕЙ 3 |
| ЯДРО | |--------------------|
| |<----| |
|---------------------| | ЯДРО |
| |
|--------------------|
Если в программе имеется только один оверлей это не приведет к
выиигрышу в памяти, т.к. в памяти помимо размера ядра резидентно
занимается место под один из оверлеев, наибольшего размера.
Для примера для рисунка :

Размер ядра - 160 К
Оверлей 1 - 60 К
Оверлей 2 - 40 К
Оверлей 3 - 30 К

Для загрузки подобной структуры необходимо 220 К памяти , хотя
суммарный объем программы 290 К. Оверлейные куски включаются в
программу на этапе линковки после компиляции . Если вы внесли
изменения в ваш оверлей вам необходимо перелинковать вашу программу.


СТРУКТУРА ОВЕРЛЕЕВ : Пока вы не используете оверлеев все
процедуры вашей программы помещаются в память резидентно при
выполнении и являются доступными из любой процедуры. При
использовании оверлеев лучшим является метод разделения процедур по

- 218 -
функциональному признаку. Это делает оверлейную структуру более
эффективной. Цель при создании оверлея - выделить функционально
независимую часть программы ,которая могла бы выполняться независимо
от других так же обособленных частей. Эта выделенная часть может
содержать любое количество процедур, функций и пр. На рисунке 2 (см
английский вариант) показано логическое и физическое разделение
файлов типа PRG. 11 файлов типа prg компилируются в 6 объектных
файлов. Основная клиппер-программа называемая DB_MAIN осуществляет
поочередный вызов оверлейных кусков , которые не связаны между собой
|---------------------------------|
| |
клиппер-программа -----> объектый модуль ----> оверлей ---->основной
модуль

add1.prg---->|add.obj | ---->|
add2.prg---->| | |
| add_edit.ovl
edit1.prg--->|edit.obj|----->|
edit2.prg--->| | |

report1.prg->|
report2.prg->|rpt.obj |------> rpt.ovl
report3.prg->|

reindex.prg-->reindex.obj---->|
| utility.ovl
backup.prg -->| b_c.obj ----->|
cleanup.prg-->|

db_main.prg ----> db_main.obj--------->db_main.exe


Рисунок 2

КАК СОЗДАТЬ ОВЕРЛЕЙ Оверлеи создаются с помощью PLINK86-Plus в
процессе линковки с использовнием файлов указателей типа .LNK Для
создания структуры определенной на рисунке 2 нужно использовать файл
указателей следующего типа:
FI Db_main
LIB Extend
DEBUG
OVERLAY Prog, $CONSTANTS
BEGINAREA
SECTION FILE Add,Edit
SECTION FILE Rpt
SECTION FILE Reindex,B_c
ENDAREA

Помните ,что линкер автоматически прилинковывает библиотеки
CLIPPER.LIB и OVERLAY.LIB. В процессе линковки происходит разделение
объектных файлов по классам. В зоне данных содержиться описание
стринговых констант и имен переменных. Кодовый сегмент содержит
описание текущих инструкций программы. Clipper обычно помещает
таблицу констант в ядро программы. Опция OVERLAY PROG, $CONSTANTS
используется для помещения данных в зону оверлеев. BEGINAREA
определяет начало зоны оверлеев.ENDAREA конец зоны оверлеев. Все
объектные файлы помещенные между командами BEGINAREA и ENDAREA

- 219 -
автоматически становяться оверлееми.
РАЗМЕЩЕНИЕ ОВЕРЛЕЕВ В ПАМЯТИ При загрузке программы с оверлееми
в память автоматически занимается память под ядро и определяется
размер памяти под оверлейные структуры , принимаемый равным
наибольшему по размеру оверлейному файлу. На рисунке 3 файл
UTILITY.OVL наибольший из трех оверлеев и соответственно размер
необходимой памяти определяется из расчета размер выполняемого файла
плюс размер указанного оверлея. При вызове друго оверлея , меньшего
размера часть памяти остается неиспользованной. Однако необходимо
помнить, что в каждый момент времени в оверлейной зоне может
находиться только один оверлей. Таким образом из оверлея возможен
вызов процедур ядра и самого оверлея, но никак не процедур
определенных в других оверлеев.
ПАМЯТЬ ДИСК
|---------------------| |--------------------|
| |<----| |
| ЗОНА |<--| | |
| ОВЕРЛЕЕВ | | | UTILITY.OVL |
| |<-|| | |
|---------------------| || |--------------------|
| ЯДРО | ||-| RPT.ovl |
| <-|| |--------------------|
|---------------------| ||--| ADD_EDIT.ovl |
| |--------------------|
|---| DB_MAIN.EXE |
| |
|--------------------|


Рисунок 3


ИСПОЛЬЗОВАНИЕ НЕСКОЛЬКИХ ОБЛАСТЕЙ ПОД ОВЕРЛЕИ Ранее
рассматривалась проблема использования одной оверлейной зоны памяти ,
но в принципе можно выделять несколько зон памя ти для загрузки
оверлеев. Для примера вы получите этот результат если немного
модифицируете командный файл для линкера.

BEGINAREA
SECTION FILE ADD,EDIT
SECTION FILE RPT
ENDAREA
BEGINAREA
SECTION FILE REINDEX
SECTION FILE B_C
ENDAREA

В данном случае сформируется следующая структура :


ДИСК ПАМЯТЬ

add_edit.ovl ---------->| overlay area 1
rpt.ovl ---------->|

b_c.ovl ---------->| overlay area 2
reindex.ovl ---------->|

- 220 -

db_main.exe ----------> root area


Рисунок 4

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


ВНЕШНИЕ И ВНУТРЕННИЕ ОВЕРЛЕИ Возможно создание двух типов
оверлеев - внешних и внутренних Функционально они одинаковы , однако
если внутренние оверлеи записаны внутри выполняемого файла, то
внешние размещаются в отдельных файлах снабжаемых расширением .OVL .
Скорость загрузки внутренних оверлеев несколько выше так как не
требует поиска отдельных файлов типа внешних оверлеев на диске.Ондако
используя внешние оверлеи вы можете грузить большие программы с
флоппи дисков или же определить размер каждого оверлея по размеру
файла. Создание внешних оверлеев происходит при помещении в опцию
SECTION ещего указателя INTO. Для примера :
BEGINAREA
SECTION INTO Add_edit.ovl FILE add,edit
SECTION INTO Rpt.ovl FILE Rpt
SECTION INTO Utility.ovl FILE reindex,b_c
ENDAREA


ВЗАИМОВКЛЮЧЕННЫЕ ОВЕРЛЕИ Имеется способность внутри одной
оверлеиной области выделить место для других оверлеев. Однако
использование этой возможности требует внимательного разделения
процедур в программе и хорошего планирования самой структуры
программы. Рисунок 5 иллюстрирует размещение оверлеев подобного типа
в памяти.

ПАМЯТЬ ДИСК ДИСК
----------------
overlay area 1 | | overlay |<------ overlay 4
|<---| area 2 |<------ overlay 5
|<-| | ----------- |
| | | overlay 3 |
|<|| ----------------
root area ||--- overlay 2
|
|---- overlay 1

В следующем примере наша клиппер-программа управления данными
модифицируется следующим образом. Создаются 2 заменяемых оверлея B_C
и REINDEX которые попеременно помещаются в зону выделенную под
объектный файл UTILMENU . Эту же зону памяти использует и файл с
объектным кодом. Создается данная структура по следующим указателям :
BEGINAREA
SECTION INTO Add_edit.ovl FILE add,edit
SECTION INTO Rpt.ovl FILE Rpt
SECTION INTO Utilmenu.ovl FILE Utilmenu
BEGINAREA
SECTION INTO Utilmenu.ovl FILE b_c

- 221 -
SECTION INTO Utilmenu.ovl FILE reindex
ENDAREA
ENDAREA

Подобное размещение оверлеев в памяти может как уменьшать так и
увеличивать необходимый размер памяти. Это зависит от размеров
различных оверлейных кусков. При управлении оверлеями , при их
создании и использовании обязательно помните следующие правила :
- размер памяти для загрузки определяется по наибольшему
оверлею;
- нельзя из оверлея ссылаться на прцедуру в другом оверлее если
они не встроенные;
- используйте мап файл для определения использования памяти
вашей программой с оверлеями.



ОПЦИЯ MAP ЛИНКЕРА PLINK 86 PLUS
--------------------------------

При указании в коммандах к линкеру опции MAP вы получаете
способность иметь карту размещения в памяти всех сегментов вашей
программы.Включение этой возможности производиться командой :
MAP = FILE.MAP S

где, FILE.MAP - имя файла куда помещается карта использования
памяти, а S специальный указатель для подтверждения необходимости
полного отчета.
Если данный указатель не стоит то создается карта-файл типа А
подробно о различных типах смотрите в приложении I.

Используете следующий файл указатель для создания карты :

FI Db_main
LIB Extend
DEBUG
OVERLAY Prog, $CONSTANTS
MAP = Db_main.map S
BEGINAREA
SECTION INTO Add_edit.ovl FILE add,edit
SECTION INTO Rpt.ovl FILE Rpt
SECTION INTO Utility.ovl FILE reindex,b_c
ENDAREA

При указании опции S в мап файл в алфавитном порядке помещаются
все программные сегменты с указанием их адреса на диске , адреса в
памяти и размера. Следующий список служит пояснением к мап файлу.

Название Столбца Содержание

Maddr адрес памяти для загрузки сегмента
Msize размер памяти под секцию
Daddr адрес на диске для сегмента
Dsize размер дисковой памяти под сегмент
Lev Номер уровня для секции резидентно = 0
Ov# Оверлейный номер секции . Не нулевой
номер в этом параметре означает , что

- 222 -
будет сегмент загружаться как оверлей.
Fth Не 0 если сегмент загружен в память
другим оверлеем.
Pload В состоянии "Yes" если произошла
загрузка через оверлейный загрузчик
до выполнения программы.

Вывод всех величин в мап файл производиться в 16-ричном коде.Мап
файлом является обыкновенный текстовый файл, который можно
распечатать.
PLINK86-Plus 2.21
Memory Map for c:DB_MAIN.EXE
Sections
Name Maddr Msize Daddr Dsize Lev Ov# Fth Pload

root 0 23370 2200 23370 0 0 0 no
add_edit 23370 ab60 60 ab60 1 1 0 no
rpt 23370 e9c0 60 e9c0 1 2 0 no
utility 23370 f670 c0 f670 1 3 0 no
329e0 a2f0 26680 a2f0 0 4 0 Yes

Просмотрев директорию диска после линковки можно определить
размер оверлейных файлов.
Директория C:\db

add_edit.ovl 43968
rpt.ovl 59936
utility.ovl 63280

Переведем значения из 16-ричной в 10-ную и получим абсолютные
значения в байтах для каждого программного сегмента :

16-ричный 10-чный
60 96
с0 192
AB60 43840
E9C0 59840
F670 63088

Cложив значения Daddr и Dsize получим значение для файла в
директории

Файл Daddr + Dsize Всего

add_edit 96 43872 43968
rpt 96 59840 59936
utility 192 63088 63280
Оверлейные файлы исходя из размера наибольшего из них
размещается по следующим 16-ричным адресам от 23370 до адреса со
смещением F670 или же в десятичной системе 63088 байт.


ПРИМЕР МАР ФАЙЛА ДЛЯ ВЛОЖЕННОЙ ОВЕРЛЕЙНОЙ СТРУКТУРЫ Отладчик
имеющийся в пакете позволяет протестировать и отладить оверлейные
куски при их загрузке в память и выполнении. Последовательность
загрузки оверлеев и их вложенность определяется как
последовательность комманд в файле указателей для линкера. При

- 223 -
использовании отладчика есть способность разложить процесс загрузки
оверлеев по шагам. В мар файле в опции Ov# указывается очередность
размещения оверлеев. Заметьте , что нижеприведенный мар файл
относиться к вложенной оверлейной структуре.
PLINK86-Plus 2.21
Memory Map for c:DB_MAIN.EXE
Sections
Name Maddr Msize Daddr Dsize Lev Ov# Fth Pload

root 0 23370 2200 23370 0 0 0 no
add_edit 23370 ab60 60 ab60 1 1 0 no
rpt 23370 e9c0 60 e9c0 1 2 0 no
utilmenu 23370 459 e0 459 1 3 0 no
reindex 237c9 7528 539 7528 2 4 3 no
b_c 237c9 8238 7a61 8238 2 5 3 no
329e0 a2f0 26680 a2f0 0 4 0 Yes

Вложенные оверлеи по мар файлу можно выделить по опции lev для
них здесь указано 2 - т.е. второй уровень вложенности. В опции Fth
определ
UTILMENU.
Помните что ядро программы постоянно находиться в памяти , а
каждый оверлейный кусок загружаясь в память в свою очередь и
производя вызов в свою область памяти своего вложенного оверлея ,
остается в памяти сам. То есть при вызове вложенного оверлея он не
замещает оверлей предок в памяти. Резидентный кусок обозначен в файле
в опции Lev значением 0. Это значение изменяется при включении внутри
оверлея новых вложенных овердлеев и находиться в интервале от 0 до 31
 ,так как в clipperе возможно до 32 уровней