ГЛАВА 5.ИНТЕРФЕЙС ПРИКЛАДНЫХ
ПРОГРАММ
Интерфейс прикладных программ Btrieve дает Вам доступ к структурам Btrieve-файлов из ваших прикладных программ. Через эти программы Ваша прикладная программа посылает вызовы, определяющие операцию для выполнения, данные для передачи или получения, информацию о статусе и позиционировании. Эта глава описывает, как вызывать Btrieve из программм, написанных на одном из следующих языков:
- IBM (или Microsoft) BASIC и BASIC-компилятор
- IBM (или Microsoft) Pascal
- Turbo Pascal
- Microsoft COBOL
- Microsoft C
- Lattice c
- Ассемблер
Для описания интерфейса, не имеющегося в данном руководстве, смотрите файл INTERFACE.DOC на программной дискете Btrieve.
ПРИМЕЧАНИЕ:
До того, как Вы сможете вызвать Btrieve из прикладной программы на любом языке, Вы должны загрузить BREQUEST (Инициатор запросов Btrieve) в память рабочей станции. ---------------------------------------------------------
СВЯЗЬ BTRIVE И BASIC
Интерфейс с Btrieve - в основном одинаков и для BASIC- компилятора, и для BASIC-интерпретатора. Для BASIC- компилятора Вы связываете интерфейс Btrieve с Вашей BASIC- программой после компиляции. Для BASIC-интерпретатора Вы загружаете интерфейс Btrieve как резидентную в памяти программу. Формат обращений к Btrieve - один и тот же для обоих. BASIC-ИНТЕРПРЕТАТОР Для вызова Btrieve из BASIC-интерпретатора Ваша прикладная программа должна инициировать выполнение BASIC с соответствующими параметрами и правильно загрузить Btrieve-интерфейс с BASIC. Если Вы не выполнили правильно эти два шага, прикладная программа Btrieve не стартует надлежащим образом, если вообще стартует. И н т е р ф е й с BASIC-интерпретатора Btrieve-интерфейс с BASIC - подпрограмма на ассемблере, называющаяся BASXBTRV.EXE, которую прикладная программа на BASIC должна вызывать для для связи с Btrieve Record Manager. В операционной системе MS-DOS BASIC-интерфейс - резидентная в памяти программа, которую вы должны загрузить до того, как Вы сможете запустить Вашу прикладную программу на BASIC. Каждая рабочая станция должна иметь свою загруженную копию BASXBTRV. После того, как Вы один раз запустили Btrieve-интерфейс с BASIC, Ваша прикладная программа может использовать операторы CALL для выполнения Btrieve-операций. Интерфейсная программа пишет одну запись в выходной файл, содержащий адрес сегмента, в который она загружена, в десятичной форме. Ваша BASIC-программа читает этот файл и использует хранящийся там адрес сегмента в операторе DEF SEG. После того, как Ваша программа выполнит DEF SEG, она может использовать оператор CALL (описанный далее в этой главе) для связи с Btrieve Record Manager. Для загрузки резидентного в памяти интерфейса введите следующую команду: <Устройство>BASXBTRV<Имя файла.Расширение> Замените <Устройство> на имя устройства, содержащего Btrieve- файлы. Замените <Имя файла.Расширение> на имя файла, который будет содержать адрес сегмента интерфейса. Вы должны задать имя файла в виде: <Устройство>:<имя файла.Расширение> Вы можете опустить <Устройство>, если Вы намерены использовать устройство, заданное по умолчанию. Как только Вы однажды загрузили интерфейс, он остается в памяти до перезапуска системы. Для сетевой среды важно, является ли заданное для BASXBTRV при инициализации имя файла локальным или уникальным именем файла. Так как адрес сегмента, куда загружается BASXBTRV, может отличаться для рабочих станций, каждая рабочая станция должна иметь свой собственный файл с адресом сегмента. Например, для загрузки BASXBTRV и задания SEGMENT.ADR в качестве файла с адресом сегмента Вы долджны запросить следующую команду: BASXBTRV SEGMENT.ADR После того, как BASIC-интерфейс загрузится в память и запишет свой адрес сегмента в файл, на дисплее появится следующее сообщение: Btrieve Basic interface loaded at segment xxxxx (Btrieve Basic интерфейс загружен в сегмент xxxxx) Ваша программа в BASIC-интерпретаторе должна включать следующие операторы чтения и определения адреса сегмента, чтобы обращаться к Btrieve: 30 OPEN "SEGMENT.ADR" FOR INPUT AS #1 'Открыть файл, содержаший адрес сегмента 40 INPUT #1, SEG.ADDR% 'Получить адрес сегмента интерфейса 50 DEF SEG = SEG.ADDR% 'Установить адрес для обращений к Btrieve Рисунок 4.1 иллюстрирует различные программы, загруженные в память, при запуске прикладной программы Btrieve, напмсанной на BASIC-интерпретаторе. Первым загружен MS-DOS, за ним следует резидентный в памяти BASIC-интерфейс - BASXBTRV. Btrieve загружен после интерфейса. Оставшаяся память доступна Вашей прикладной программе. Начало памяти>>> ------------------------------¬ ¦ ¦ ¦ DOS 3.x ¦ ¦ ¦ +-----------------------------+ ¦ ¦ ¦ BASXBTRV ¦ ¦(Интерфейс BASIC-интерпрет.) ¦ ¦ ¦ +-----------------------------+ ¦ ¦ ¦ BREQUEST ¦ ¦ ¦ +-----------------------------+ ¦ ¦ ¦Прикладная программа Btrieve ¦ ¦ ¦ L------------------------------ <<Конец памяти Рисунок 5.1 Карта резидентного в памяти BASIC-интерфейса
З а п у с к BASIC-интерпретатора
Обычно BASIC допускает длину записи 128 байт для любого открываемого программой файла. Для доступа к Btrieve-файлу с длиной логической записи большей 128 байтов Вы должны включить параметр размера файла, задающий длину логической записи файла, в команду, вызывающую BASIC-интерпретатор: BASIC [/S:yyy] В приведенном выше примере yyy - длина логической записи самого большого Btrieve-файла, к которому Ваша программа будет иметь доступ. См. руководство по BASIC для дополнительной информации по заданию этой опции. BASIC-КОМПИЛЯТОР Для выполнения программы BASIC-компилятора, обращающейся к Btrieve, Вы должны связать программы соответствующего Btrieve- интерфейса с об'ектным файлом BASIC-компилятора. Btrieve- дискеиа содержит файл, который Вы должны включить в Ваш редактор BASIC-а: BASXBTRV.OBJ. Подробное описание редактора связей см. в руководстве по Вашей операционной системе и по BASIC. Для редактирования связей BASIC-программы, для которой об'ектный файл хранится в файле BASPROG, с Btrieve-интерфейсом BASICа BASXBTRV.OBJ Вы должны ответить на подсказку редактора связей для об'ектных модклей следующим образом: Object Modules [.OBJ]:basprog+basxbtrv ----------------------------------------------------------- ПРИМЕЧАНИЕ: Microsoft Quick BASIC использует файл QBIXBTRV.OBJ как программу Btrieve-интерфейса и требует процедуры, отличные от других версий BASIC-а, для открытия файлов и просмотра буфера данных. См. файл INTRFACE.DOC на дискете "PROGRAM" -----------------------------------------------------------
ВЫЗОВ BTRIEVE ИЗ BASIC
При использовании BASIC-компилятора и BASIC-интерпретатора шаги для вызова Btrieve - одни ите же. Для доступа к данным Btrieve- файла Ваша BASIC-прикладная программа должна сперва выполнить стандартный оператор BASICа OPEN NUL для размещения буфера:
OPEN "NUL" AS # 1
Когда BASIC выполнит оператор OPEN, он разместит область "Блок
управления файлами" (FCB). Этот блок содержит помимо других вещей область буфера, в которой хранятся данные из файла во время передачи их на диск и с диска. BASIC позволяет вам определять эту буферную область как набор непрерывных строковых переменных в операторе FIELD.
Например, если Вы задаете файл адресов, Ваша прикладная программа должна включать следующий оператор:
FIELD #1, 30 AS NAM$, 30 AS STREETS$, 30 AS CITY$, 2 AS STATE$, 5 AS ZIP$
Этот оператор показывает, что буфер полей, предварительно распределенный для файла #1, содержит записи, в которых первые 30 символов содержат имя, следующие 30 символов - улицу и т.д.
BASIC ограничивает весь оператор длиной 255 символов. Если Ваша запись содержит очень много полей, Вы может быть и не сумеете полностью описать Ваши данные в одном операторе BASIC. BASIC позволяет применять столько операторов FIELDS, сколько потребуется для описания записей. Различные имена во всех операторах FIELD применимы в одно и то же время. Каждый новый оператор FIELD переопределяет буфер с позиции первого символа. Поэтому Вы должны использовать фиктивное поле как первый вход в последовательности операторов FIELD для расчета полей, которые были уже заданы.
Например, если записи определенные предыдущим оператором FIELD содержали номер телефона после почтового индекса, Вы можете определить поле номера телефона в следующем операторе:
FIELD #1, 97 AS DUMMY$, 7 AS PHONE$
Так как Btrieve использует буфер в FCB для передачи записей, прикладная программа должна включать оператор FIELD для того, чтобы иметь доступ к данным, возвращаемым Btrieve. Смотрите руководство по BASIc для полного описания операторов OPEN и FIELD. вы должны использовать команду LSET для сохранения значений в буфере, определенном оператором FIELD.
После того, как стандартный оператор BASIC OPEN откроет Btrieve- файл, Ваша прикладная программа готова посылать запросы Btrieve Record Manager. Сперва Ваша прикладная программа выполняет Btrieve-операцию Open. После этого Btrieve обрабатывает все чтения, записи и модификации файлов через btrieve-запросы. Ваша прикладная пограмма должна выполнить Btrieve-операцию Close для завершения работы.
Все обращения к Btrieve из BASIc должны быть в следующем формате:
CALL BTRV (Операция, Статус, FCB, Длина буфера данных, Буфер ключа, Номер ключа)
Для BASIC-интерпретатора BTRV должно быть числом 0. В BASIC- компиляторе BTRV - внешнее имя, разрешаемое редактором связей. Хотя при каждом обращении требуются все параметры, Btrieve не использует все параметры для каждой операции. В некоторых случаях Btrieve игнорирует их значение. Более детальное описание параметров смотрите в Главе 5 этого руководства. Следующие разделы описывают каждый параметр.
К о д о п е р а ц и и
Параметр операции определяет, какую Btrieve-функцию вы хотите выполнить. Задаваемая Вами переменная должна быть целого типа и может быть одним из допустимых кодов Btrieve-операции, описанных в Главе 6 этого руководства. (также смотрите Приложение A для полного списка этих кодов). ваша прикладная программа должна задавать правильный код операции при каждом обращении к Btrieve. Btrieve Record Manager никогда не изменяет код.
К о д с т а т у с а
Параметр статуса содержит значение кода, показывающее на возникновение ошибки во время Btrieve-операции. Btrieve Record Manager возвращает код статуса 0 после успешной операции. Btrieve показывает на все ошибки во время выполнения, возвращая ненулевое значение в параметр кода статуса.
Прикладная программа на Бейсике должна всегда посылать целую переменную как параметр статуса при Btrieve-вызове. После Btrieve- вызова прикладная программа должна всегда проверять значение переменной статуса для определения, был ли вызов успешно завершен. Смотрите в Приложении B список собщений об ошибках Btrieve и их вероятных причинах.
Б л о к у п р а в л е н и я ф а й л о м
BASIC размещает область "Блока управления файлом" (FCB) при выполнении оператора OPEN. Btrieve использует этот блок для поддержки своей позиционной информации и передачи записей данных. Поэтому Ваша прикладная программа должна передавать адрес FCB для Record Manager при каждом обращении. Ваша прикладная программа должна использовать разные адреса FCB для каждого отдельного Btrieve-файла, к которому она имеет доступ.
Для определения адреса FCB Ваша прикладная программа на Бейсике должна использовать оператор VARPTR. В следующем примере BASIC возвращает адрес FCB для файла, открытого как #1, в целую переменную FCB.ADDR%.
FCB.ADDR% = VARPTR(#1)
Смотрите руководство по BASIC для полного описания оператора VARPTR.
Д л и н а б у ф е р а д а н н ы х
Для любой операции, использующей буфер данных, Ваша прикладная программа должна передавать длину буфера данных как целую переменную. Для файла с записями фиксированной длины этот параметр должен показывать длину записи, заданную при создании файла. Когда Вы добавляете записи или корректируете файл с записями переменной длины, этот параметр должен равняться длине записи, заданной при создании файла, плюс количество символов включенных за фиксированной частью записи. Когда Вы ищете записи переменной длины, этот параметр должен быть достаточно большим для размещения самой длинной записи файла.
Б у ф е р к л ю ч а
При каждом Btrieve-обращении Ваша BASIC- программа должна передать строковую переменную, содержащую значение ключа. Если значение ключа - целое число, Ваша прграмма должна перевести ее в строковую, используя оператор MKI$ до обращения к Btrieve. Если ключ состоит из двух или более разрывных сегментов, вы должны объединить их в одну строковую переменную и передать эту переменную как буфер ключа. В зависимости от операции ваша программа может устанавливать переменные или Record Manager может возвращать их.
Record Manager возвращает ошибку, если строковая переменная, передаваемая как буфер ключа, короче, чем заданная длина ключа. Если первый вызов Вашей прикладной программы не требует инициализации буфера ключа, Вы должны присвоить строковой переменной значение SPACEUNDEF, где x представляет заданную длину ключа. До тех пор, пока Ваша прикладная программа не присвоит в BASIC значение строковой переменной, она будет иметь длину 0.
Н о м е р к л ю ч а
Вы можете задавать до 24 различных ключей при создании Btrieve- файла. Когда Ваша прикладная программа будет иметь доступ к файлу, она должна сообщить Record Manager путь доступа для операции. Параметр номера ключа - целая переменная со значением от 0 до 23, где 0 -сегмент первого ключа. определенного для файла. Btrieve никогда не повторяет это значение.
ПРИМЕР СПИСКА ПАРАМЕТРОВ
BASIC-программа, показанная ниже на Рисунке 4.2, открывает Btrieve-файл и ищет запись данных, соответствующую первому
значению ключа 0 - полю имени.
'Строки с 5 по 20 применимы только для BASIC-интерпретатора.
'Не включайте их в BASIC-компилятор
5 BTRV = 0
10 OPEN "SEGMENT.ADR" FOR INPUT AS #1
15 INPUT #1, SEG.ADDR%
20 DEF SEG = SEG.ADDR%
30 OPEN "NUL" AS #2
40 FIELD #2, 30 AS NAME$, 30 AS STREETS$,
30 AS CITY$, 2 AS STATE$, 6 AS ZIP$
50 OP% = 0 : STATUS% = 0
70 FCB.ADDR% = VARPTR(#2) : BUF.LEN% = 98
80 KEY.BUF$ = "ADDRESS.BTR
90 KEY.NUM% = 0
100 CALL BTRV(OP%,STATUS%,FCB.ADDR%,BUF.LEN%,KEY.BUF$,KEY.NUM%)
110 IF STATUS% <> O THEN
PRINT "Ошибка открытия файла. Статус =", STATUS% : END
120 OP% = 12
125 KEY.BUF$ = SPACEUNDEF
130 CALL BTRV(OP%,STATUS%,FCB.ADDR%,BUF.LEN%,KEY.BUF$,KEY.NUM%)
140 IF STATUS% <> O THEN
PRINT "Ошибка открытия файла. Статус =", STATUS% : END 150 PRINT "Первая запись файла",NAM$,STREET$,CITY$,STATE$,ZIP$
Рисунок 5.2 Btrieve-вызов из BASIC
СВЯЗЬ BTRIVE И PASCAL
Для доступа к Btrieve-файлам прикладная программа на Паскале должна задать BTRV как целую функцию. Когда Ваша прикладная программа вызывает эту функцию, она выполняет различные типы доступа к файлу в зависимости от заданных параметров. Интерфейс Паскаля взаимодействует с Btrieve Record Manager. Вы должны загрузить Record Manager, резидентную в памяти программу на ассемблере, до запуска Вашей прикладной программы.
Объявите Btrieve-функцию как внешнюю для IBM (или Microsoft) Pascal. Btrieve обеспечивает маленькой программой на ассемблере которую вы можете связать с Вашей прикладной программой на Паскале как внешнюю функцию. Для Turbo Pascal Btrieve обеспечивает исходный код интерфейса таким образом, что вы можете включить его с Вашей программой на Паскале для компиляции.
Программная дискета Btrieve содержит файл, требуемый для включения в Ваш исходный файл на Паскале. Для IBM Pascal файл содержит объявление внешней функции для BTRV. Для Turbo Pascal файл содержит код всего Btrieve-интерфейса.
Ваша прикладная программа получает доступ ко всем Btrieve-файлам, вызывая функцию BTRV. Это -целая функция, возвращающая статус операции. Если вы используете IBM (или Microsoft) Pascal, используйте метакоманду $INCLUDE для подключения файла BEXTERN114S. пример ниже показывает как определена внешняя функция BTRV:
function BTRV ( OP : integer; vars POS_BLOCK : string; vars DATA_BUFFER : string; vars DATA_LEN : integer; vars KEY_BUFFER : string; KEY_NUMBER : integer ) :integer; extern;
Если вы используете Turbo Pascal, применяйте команду $I для подключения файла TURXBTRV114S. Btrieve-функция определяется следующим образом:
function BTRV ( OP : integer; var POS_BLOCK, var DATA_BUFFER; var DATA_LEN : integer; var KEY_BUFFER; KEY_NUMBER : integer ) :integer;
КОМПОНОВКА ПРИКЛАДНОЙ PASCAL-ПРОГРАММЫ С BTRIEVE
Если вы используете IBM (или Microsoft) Pascal, вы должны подключить файл PASXBTRV.OBJ к редактору связей Паскаля. Для компановки объектного файла Паскаля (PASPROG) с интерфейсом IBM Pascal Вы должны ответить на подсказку редактора связей следующим образом:
Object Modules[.OBJ]:pasprog+pasxbtrv
Если Вы используете Turbo Pascal подключайте исходный файл интерфейса TURXBTRV114S к Вашей программе при компиляции.
ВЫЗОВ BTRIEVE ИЗ PASCAL
Ваша Pascal-прикладная программа никогда не должна выполнять стандартный ввод/вывод Паскаля для Btrieve-файлов. Ваша прикладная программа должна выполнять весь ввод/вывод Btrieve- файла с помощью Btrieve-функций. Первый Btrieve-вызов, который должна выполнить Ваша прикладная программа, -операция Open. Вслед за этим Вы можете читать, писать и модифицировать файлы через обращения к Btrieve. До завершения Вашей прикладной программы необходимо выполнить Btrieve-операцию Close.
Все обращения к Btrieve должны быть выполнены через BTRV- функцию. Результат функции всегда целое значение, соответствующее одному из кодов статуса, перечисленных в Приложении B. После вызова Btrieve ваша прикладная программа должна всегда проверять значение переменной статуса. Статус 0 показывает на успешное выполнение операции. Ваша прикладная программа должна быть способна распознавать и принимать решения по ненулевым статусам.
Хотя при каждом обращении требуются все параметры, Btrieve не использует все параметры для каждой операции. В некоторых случаях Btrieve игнорирует их значение. Более детальное описание параметров смотрите в Главе 5 этого руководства. Следующие разделы описывают каждый параметр.
К о д о п е р а ц и и
Параметр операции определяет, какой тип Btrieve-функции Вы хотите выполнить. Ваша прикладная программа должна быть способна задавать правильный код операции при каждом обращении к Btrieve. Record Manager никогда не изменяет код операции. Задаваемая Вами переменная должна быть целого типа и может быть одним из допустимых кодов операций, описанных в Главе 6. Приложение A содержит полный список этих кодов
Б л о к п о з и ц и и
Ваша прикладная программа должна размещать отдельный блок позиции для каждого открываемого Btrieve-файла. Btrieve инициализирует блок позиции при выполнении операции Open и ссылается и корректирует данные в блоке позиции при всех операциях над файлами. Поэтому Ваша прикладная программа должна посылать один и тот же блок позиции при всех последовательных Btrieve-операциях над файлами. Когда Ваша прикладная программа имеет более одного открытого файла одновременно, btrieve использует блок позиции для определения, на какой файл ссылаются при каком-либо вызове. Вдобавок, Ваша прикладная программа никогда не должна изменять значения в блоке позиции.
IBM Pascal прикладная программа должна размещать 128-байтовую строку для блока позиции. Если вы используете Turbo Pascal, Вы должны размещать параметр блоак позиции как 128-байтовый символьный массив.
Б у ф е р д а н н ы х
Буфер данных содержит записи, передавемые Вашей прикладной программой в Btrieve и из него. Btrieve ожидает строковый тип для IBM Pascal. Для Turbo Pascal вы можете использовать любой тип данных.
Вы можете захотеть задать структуру записи Паскаля для описания
данных, хранимых в файле. Для передачи переменной типа записи в IBM Pascal применяйте опцию case для задания переменной строкового типа структуры. Для Turbo Pascal Вы можете посылать саму запись.
Когда Вы вычисляете длину переменной строки, примите в расчет, что элементы четной длины в записи могут потребовать дополнительный байт для хранения, независимо от того, была ли упакована запись или нет. Это также важно рассматривать при определении длины записи для утилиты CREATE. Смотрите руководство по Паскалю для дополнительной информации о типах записи.
Д л и н а б у ф е р а д а н н ы х
Для любой операции, использующей буфер данных, Ваша прикладная программа должна передавать длину буфера данных как целую переменную. Для файла с записями фиксированной длины этот параметр должен показывать длину записи, заданную при создании файла.
Когда Вы добавляете записи или корректируете файл с записями переменной длины, этот параметр должен равняться длине записи, заданной при создании файла, плюс количество символов включенных за фиксированной частью записи. Когда Вы ищете записи переменной длины, этот параметр должен быть достаточно большим для размещения самой длинной записи файла.
Б у ф е р к л ю ч а
Ваша прикладная программа должна передать строковую переменную для IBM Pascal или переменнуб любого типа для Turbo Pascal, содержащую значение ключа при каждом обращении к Btrueve. В зависимости от операции Ваша прикладная программа может устанавливать эту переменную или Record Manager может возвращать ее.
Ддя IBM Pascal, если значение ключа - целое число, Вы должны определить ее как структуру записи с двумя переменными. Одна переменная определяет ключ как целое. другая определяет его как двухсимвольную строку. Вы должны использовать строковую переменную для обращений к Btrieve.
Для Turbo Pascal Вы можете передавть сам буфер ключа, независимо от типа.
Если ключ состоит из двух или более сегментов, используйте структуру записи для определения полей ключа. Затем используйте переменную для передачи буфера ключа в Btrieve.
Н о м е р к л ю ч а
Вы можете задавать до 24 различных ключей при создании Btrieve-
файла. Поэтому Ваша прикладная программа должна сообщить Record Manager путь доступа для данной операции. Параметр номера ключа - целая переменная со значением от 0 до 23, где 0 -сегмент первого ключа. определенного для файла. Record Manager никогда не повторяет этот параметр.
ПРИМЕР СПИСКА ПАРАМЕТРОВ
IBM (или Microsoft) Pascal-программа, показанная ниже на Рисунке 5.3, открывает Btrieve-файл и ищет запись данных, соответствующую первому значению ключа 0 - полю имени.
const B_GET_FST = 12; B_OPEN = 0; type ADDRESS_REc = record case integer of 1: (NAME : string(30); STREET : string(30); CITY : string(30); STATE : string(2); ZIP : string(5)); 2: (ENTIRE : string(98)); end; var DATA_BUF : ADDRESS.REC; DB_LEN : integer; FILE_NAME : string(14); KEY_BUF : string(30); POS_BLOCK : string(128); STATUS : integer; begin FILE_NAME :='B:ADDRESS.BTR'; STATUS :=BTRV(B_OPEN,POS_BLOCK,DATA_BUF.ENTIRE,DB_LEN, FILE_NAME,0); if STATUS <> O then begin writelen(OUTPUT,'Ошибка открытия файла. Статус =', STATUS); return; end; DB_LEN :=sizeof(ADDRESS_REC); STATUS :=BTRV(B_GET_FST,POS_BLOCK,DATA_BUF.ENTIRE,DB_LEN, KEY_BUF,0); if STATUS <> O then begin writelen(OUTPUT,'Ошибка открытия файла. Статус =', STATUS); else writelen(OUTPUT,'Первая запись файла',DATA_BUF.ENTIRE); end.
Рисунок 5.3 Обращение к Btrieve из IBM PAscal
Рисунок 5.4 показывает ту же самую программу, написанную на Turbo Pascal. Это единственный пример для Turbo Pascal в этом руководстве. Все другие примеры приведены для IBM (Microsoft) Pascal.
На рисунке 5.4 прикладная программа использует символьные массивы вместо строк для полей в буфере данных и буфере ключа, потому что Turbo Pascal хранит байт двоичной длины в первой позиции строкового поля при инициализации поля. Если Вы пытаетесь использовать такое значение как ключ Btrieve-файла без определения его как l-строки, результат будет непредсказуем. Когда Btrieve сравнивает значения ключей при случайном или последовательном поиске, он сравнивае их байт за байтом от абсолютного базиса. Байт длины рассматривается как часть значения вместо индикатора длины, пока ключ не будет определен как l-строка.
Хотя пример на Рисунке 5.4 использует переменные записи для параметров блока позиции, буфера данных и буфера ключа, Btrieve не требует этого от Вас. Этот пример просто иллюстрирует один из способов написания программы.
const B_GET_FST = 12; B_OPEN = 0; type ADDRESS_REC = record {Structure of address file entry} case integer of 1: (NAME : array[1..30] of char; STREET : array[1..30] of char; CITY : array[1..30] of char; STATE : array[1..2] of char; ZIP : array[1..5] of char; 2: (START : integer); end; FILE_NAME = record case integer of 1:(VALUE : array[1..14] of char); 2:(START : integer); end; KEY_BUF = record case integer of 1:(VALUE : array[1..30] of char); 2:(START : integer); end;
var DATA_BUF : ADDRESS.REC; DB_LEN : integer; FNAME : FILE_NAME; KBUF : KEY_BUF; POS : record case integer of 1:(START : integer); 2:(BLK :array[1..128] of byte); end; STATUS : integer; I : integer; {$I TURXBTRV119S} begin FNAME.VALUE :='B:ADDRESS.BTR'; STATUS :=BTRV(B_OPEN,POS_START,DATA_BUF.START,DB_LEN, FNAME.START,0); if STATUS <> O then writelen(OUTPUT,'Ошибка открытия файла. Статус =', STATUS) else begin DB_LEN :=sizeof(ADDRESS_REC); STATUS :=BTRV(B_GET_FST,POS.START,DATA_BUF.START,DB_LEN, KBUF.STAT,0); if STATUS <> O then writelen(OUTPUT,'Ошибка открытия файла. Статус =', STATUS) else writelen(OUTPUT,'Первая запись файла',DATA_BUF.NAME, DATA_BUF.STREET,DATA_BUF.CITY,DATA_BUF.STATE, DATA_BUF.ZIP); end; end.
Рисунок 5.4 Обращение к Btrieve из Turbo Pascal
СВЯЗЬ BTRIVE И C
Btrieve-дискета содержит интерфейс для Microsoft и Latice C и для других компиляторов C. Формат обращений к Btrieve идентичен для всех. Связь с другими компиляторами C смотрите в Приложении F которое описывает, как связать Btrieve из ассемблера.
Ваша Btrieve программная дискета содержит исходный код для каждого из этих интерфейсов. Весь C-интерфейс написан на C.
Для доступа к Btrieve-файлу Ваша прикладная программа должна вызвать целую функцию BTRV. Btrieve обеспечивает небольшой интерфейсной программой, связывающей Btrieve Record Manager с Вашей прикладной программой на C. Вы должны загрузить Record Manager до того, как стартуете Вашу прикладную программу.
КОМПОНОВКА ПРИКЛАДНОЙ C-ПРОГРАММЫ С BTRIEVE
После успешной компиляции программы на C скомпануйте ее с C-интерфейсом. Метод, применяемый при компоновке с C-интерфейсом, немного зависит от применяемого Вами компилятора C. Полное описание компоновки смотрите в руководствах по операционной системе и по компилятора.
Если вы используете компилятор Microsoft C, Вы должны скомпилировать интерфейсный файл MSCXBTRV.C с помощью Вашего компилятора. Если Вы компилируете большую модель, Вы должны отредактировать исходный файл интерфейса и сделать изменения, описанные в этом документе. Компануйте Вашу прикладную программу как показано ниже в примере:
Object Modules[.OBJ]:c+cprog+mscxbtrv
ВЫЗОВ BTRIEVE ИЗ C
Ваша прикладная программа никогда не должна выполнять стандартный ввод/вывод C для Btrieve-файлов. Ваша прикладная программа должна выполнять весь ввод/вывод Btrieve- файла с помощью Btrieve-функций. После выполнения операции Open Ваша программа можете читать, писать и модифицировать файлы через обращения к Btrieve. До завершения Вашей прикладной программы необходимо выполнить Btrieve-операцию Close.
Ваша прикладная программа выполняет обращения к Btrieve через целую функцию BTRV. Результат функции всегда целое значение, соответствующее одному из кодов статуса, перечисленных в
Приложении B. После вызова Btrieve Ваша прикладная программа должна всегда проверять значение переменной статуса. Статус 0 показывает на успешное выполнение операции. Ваша прикладная программа должна быть способна распознавать и принимать решения по ненулевым статусам.
Функция BTRV ожидает параметры следующего типа:
int BTRV(OP,POS_BLK,DATA_BUF,BUF_LEN,KEY_BUF,KEY_NUM) int OP; /* код операции */ char POS_BLK[]; /* блок позиции */ char DATA_BUF[]; /* буфер данных */ int *BUF_LEN; /* длина буфера данных */ char KEY_BUF[]; /* буфер ключа */ int KEY_NUM; /* номер ключа */
Хотя при каждом обращении требуются все параметры, Btrieve не использует все параметры для каждой операции. В некоторых случаях Btrieve игнорирует их значение. Более детальное описание параметров смотрите в Главе 5 этого руководства. Следующие разделы описывают каждый параметр.
К о д о п е р а ц и и
Параметр операции определяет, какой тип Btrieve-функции Вы хотите выполнить. Могут быть операции чтения, записи, удаления или корректировки. Ваша прикладная программа должна быть способна задавать правильный код операции при каждом обращении к Btrieve. Record Manager никогда не изменяет код операции. Задаваемая Вами переменная должна быть целого типа и может быть одним из допустимых кодов операций, описанных в Главе 6. Приложение A содержит полный список этих кодов.
Б л о к п о з и ц и и
Прикладная программа на C размещает 128-байтовый массив, который Btrieve использует для хранения структур ввода/вывода файла и позиционной информации, описанной в Главе 2. Btrieve инициализирует этот массив, когда Ваша прикладная программа выполняет операцию Open. Btrieve ссылается на данные этого массива и корректирует их при всех операциях над файлом. Ваша прикладная программа никогда не должна изменять значения, хранящиеся в этом массиве.
Когда Ваша прикладная программа имеет более одного открытого файла одновременно, Btrieve использует блок позиции для определения, на какой файл ссылаются при каком-либо вызове. Ваша прикладная программа должна размещать отдельный блок позиции для каждого открываемого Btrieve-файла.
Б у ф е р д а н н ы х
Параметр буфера данных - адрес массива или переменной типа структуры, содержащей записи, передавемые Вашей прикладной программой в Btrieve-файл и из него. Удостовертесь, что Вы размещаете достаточно большой буфер данных для размещения самой длинной записи в файле. если буфер слишком мал, Btrieve-запросы могут повредить данные, следующие за буфером данных.
Д л и н а б у ф е р а д а н н ы х
Для любой операции, использующей буфер данных, Ваша прикладная программа должна передавать адрес целой переменной, содержащей длину буфера данных. Для файла с записями фиксированной длины этот параметр должен показывать длину записи, заданную при создании файла.
Когда Вы добавляете записи или корректируете файл с записями переменной длины, этот параметр должен равняться длине записи, заданной при создании файла, плюс количество символов включенных за фиксированной частью записи. Когда Вы ищете записи переменной длины, этот параметр должен быть достаточно большим для размещения самой длинной записи файла.
Б у ф е р к л ю ч а
Ваша прикладная программа должна передать адрес переменной, содержащей значение ключа при каждом обращении к Btrieve. Если вы определяете ключ как двоичное, когда Вы впервые создаете файл, вы должны определить переменную типа int, long или unsigned. Если Вы определили ключ как строку, Вы должны определить переменную буфера ключа как структуру или символьный массив. Если ключ состоит из двух или более сегментов, используйте переменную структуры, состоящую из полей сегментов в правильном порядке. В зависимости от операции Ваша прикладная программа может устанавливать эту переменную или Btrieve Record Manager может возвращать ее.
Btrieve не может определить длину буфера ключа при вызове из программы на C. Поэтому вы должны удостовериться, что буфер - по крайней мере не меньше длины ключа, заданной Вами при создании файла. Иначе Btrieve-запросы могут разрушить данные, хранящиеся в памяти за буфером ключа.
Н о м е р к л ю ч а
Вы можете задавать до 24 различных ключей при создании Btrieve- файла. Поэтому Ваша прикладная программа должна сообщить Record Manager путь доступа для данной операции. Параметр номера ключа - целая переменная со значением от 0 до 23, где 0 -сегмент первого ключа. определенного для файла. Record Manager никогда не
повторяет этот параметр.
ПРИМЕР СПИСКА ПАРАМЕТРОВ
C-программа на Рисунке 5.6 открывает Btrieve-файл и ищет запись данных, соответствующую первому значению ключа 0 - полю имени.
#define B_OPEN 0
#define B_FIRST 12
main(){
struct ADDR_REC /* Структура записи адреса в файле*/ { char NAME[30]; char STREET[30]; char CITY[30]; char STATE[2]; char ZIP[5]; };
struct ADDR_REC ADDR_BUF;
int DB_LEN;
char KEY_BUF[30];
char POS_BLK[128];
int STATUS;
STATUS =BTRV(B_OPEN,POS_BLK,&ADDR_BUF,&DB_LEN,"ADDRESS.BTR",0); if (STATUS != O)
{ print("Ошибка открытия файла. Статус = %d", STATUS); exit(0); } DB_LEN = sizeof(ADDR_BUF);
STATUS = BTRV(B_FIRST,POS_BLK,&ADDR_BUF,&DB_LEN,KEY_BUF,0); if (STATUS != O)
print("Ошибка открытия файла. Статус = %d", STATUS); else
print("Первая запись файла: %.97s",&ADDR_BUF); };
Рисунок 5.6 Обращение к Btrieve из C
СВЯЗЬ BTRIVE И АCСЕМБЛЕРА
Если Вы используете ассемблер или язык программирования, для которого нет интерфейса на Btrieve-дискете, Вы можете создать интерфейс, применяя ассемблер. Программа связи Btrieve с ассемблером требует выполнения трех основных шагов:
- Хранения Btrieve-параметров в памяти в формате, ожидаемом Btrieve Record Manager
- Проверки, что Record Manager был загружен в память
- Вызова Record Manager с помощью выполнения прерывания, передающего управление Btrieve
ХРАНЕНИЕ ПАРАМЕТРОВ
Предыдущие разделы этой главы описывали только семь Btrieve- параметров: статус, код операции, блок позиции, буфер данных, длина буфера данных, буфер ключа и номер ключа. (BASIC-интерфейс объединяет блок позиции и буфер данных в один параметр - FCB. Паскаль и C интерфейс возвращают код статуса как значение функции.)
В действительности Record Manager ожидает десять параметров. Программы интерфейса с языками, обеспечиваемые Btrieve, извлекают три параметра до передачи управления Record Manager. Для создания на ассемблере своего собственного интерфейса с Btrieve Вы должны проинициализировать все десять параметров. Следующий рисунок показывает все десять параметров Btrieve и их формат.
--------------T----------T-----------------------------¬ ¦ N параметра ¦ Смещение ¦ Содержание ¦ +-------------+----------+-----------------------------+ ¦ 1 ¦ 0 ¦ смещение буфера данных ¦ +-------------+----------+-----------------------------+ ¦ ¦ ¦ сегмент буфера данных ¦ +-------------+----------+-----------------------------+ ¦ 2 ¦ 4 ¦ длина буфера данных ¦ +-------------+----------+-----------------------------+ ¦ 3 ¦ 6 ¦ смещение позиц.информации ¦ +-------------+----------+-----------------------------+ ¦ ¦ ¦ сегмент позиц.информации ¦ +-------------+----------+-----------------------------+ ¦ 4 ¦ 10 ¦ смещение FCB ¦ +-------------+----------+-----------------------------+ ¦ ¦ ¦ сегмент FCB ¦ +-------------+----------+-----------------------------+ ¦ 5 ¦ 14 ¦ код операции ¦ +-------------+----------+-----------------------------+ ¦ 6 ¦ 16 ¦ смещение буфера ключа ¦ +-------------+----------+-----------------------------+ ¦ ¦ ¦ сегмент буфера ключа ¦ +-------------+----------+-----------------------------+ ¦ 7,8 ¦ 20 ¦ длина ключа | номер ключа ¦ +-------------+----------+-----------------------------+ ¦ 9 ¦ 22 ¦ смещение статуса ¦ +-------------+----------+-----------------------------+ ¦ ¦ ¦ сегмент статуса ¦ +-------------+----------+-----------------------------+ ¦ 10 ¦ 26 ¦ ID интерфейса ¦ L-------------+----------+------------------------------ Рисунок 5.7 Структура Btrieve-параметров
До того, как Вы сможете обратиться к Btrieve, Вы должны проинициализировать область данных, содержащую все десять параметров, перечисленных на Рисунке 5.1. Храните смещение этой области данных в регистре DX. Btrieve ожидает адрес блока параметров в DS:DX, когда он получает управление.
ОПИСАНИЕ ПАРАМЕТРОВ
Следующие разделы описывают исе десять параметров, ожидаемых Btrieve при использовании программы интерфейса на ассемблере.
Б у ф е р д а н н ы х
Передавайте буфер данных как двойное слово, содержащее адрес сегмента и смещение буфера данных прикладной программы. Буфер данных - область, используемая для передачи записей между прикладной программой и Record Manager.
Д л и н а б у ф е р а д а н н ы х
Передавайте длину буфера данных как слово, содержащее длину буфера данных. Прикладная программа передает интерфейсу адрес целой переменной, содержащей длину буфера данных. Интерфейс должен скопировать значение длины буфера данных в блок параметра передаваемого Btrieve. После возврата из Btrieve-прерывания интерфейс должен скопировать значение длины буфера данных из блока параметра обратно по адресу, заданному прикладной программой.
П о з и ц и о н н а я и н ф о р м а ц и я
Передавайте позиционную информацию как двойное слово, содержащее адрес сегмента и смещение 90-байтовой области данных, используемой Btrieve для хранения позиционной информации файла.
Это один из параметров, извлекаемых Btrieve-интерфейсом прикладной программы. В BASIC эта область получается из FCB. В других языках для этой цели используется часть параметра блока позиции. Вы должны обеспечить Record Manager адресом 90-байтовой области для использования при вызове Btrieve из ассемблера. Та же самая область данных должна быть передана в Btrieve при всех обращениях к тому же файлу.
FCB
Передавайте FCB как двойное слово, содержащее адрес сегмента и смещение 38-байтовой области данных, используемой Btrieve для хранения DOS FCB. Это один из параметров, извлекаемых Btrieve- интерфейсом прикладной программы. В BASIC эта область получается из BASIC FCB. В других языках для этой цели используется часть параметра блока позиции. Вы должны обеспечить Record Manager адресом 38-байтовой области для использования при вызове Btrieve из ассемблера. Тот же самый FCB должен быть передан в Btrieve при всех обращениях к тому же файлу.
К о д о п е р а ц и и
Передавайте код операции как слово, содержащее дкод операции Btrieve. Это должен быть один из кодов Btrieve-операции, перечисленных в Приложении A.
Б у ф е р к л ю ч а
Передавайте буфер ключа как двойное слово, содержащее адрес сегмента и смещение буфера ключа прикладной программы.
Д л и н а к л ю ч а
Передавайте длину ключа как байт, содержащий длину буфера ключа. Это один из параметров, извлекаемых Btrieve-интерфейсом прикладной программы, который Вы должны обеспечить при вызове Btrieve из ассемблера.
Интерфейсы Btrieve с COBOL и C не могут определить длину буфера ключа, так как он не передается с типом данных при компиляции. В этих случаях Btrieve передает максимальную допустимую длину ключа. Record Manager никогда не будет записывать буфер ключа за заданную длину ключа. Record Manager возвратит ошибку, если этот параметр короче, чем заданная длина ключа.
Н о м е р к л ю ч а
Передавайте номер ключа как байт, содержащий номер ключа, с помощью которого можно получить доступ к файлу.
К о д с т а т у с а
Передавайте код статуса как двойное слово, содержащее адрес сегмента и смещение параметра статуса. Это адрес, по которому Btrieve будет хранить код статуса после выполнения операции.
ID и н т е р ф е й с а
Передавайте ID интерфейса как слово, проинициализированное значением 06176H. Если Вы установите идентификатор в любое другое значение, Btrieve не позволит иметь доступ к записям переменной длины. Эта проверка позволяет Btrieve определять, был ли он вызван из прикладных программ, скомпанованных с предыдущими версиями интерфейса, которые не понимают записи переменной длины7
ПРОВЕРКА ЗАГРУЗКИ RECORD MANAGER
Как только параметры проинициализированы, проверьте, что Record Manager загружен, до обращения к нему. Когда Record Manager загружен, он хранит точку входа в векторе прерываний 07BH. Удостоверьтесь, что слово вектора прерывания 07BH проинициализировано значением 033H, чтобы интерфейс мог определить, загружен ли Record Manager.
ВЫЗОВ RECORD MANAGER
После того, как Вы сохранили адрес Btrieve-параметров в DX и проверили, что Record Manager загружен, Вы готовы к вызову Btrieve. выполните прерывание 07BH и Record Manager выполнит Ваш запрос. Когда операция выполнена, Record Manager вернет управление в Вашу программу по инструкции, следующей за прерыванием. Следующий пример показывает программу, которая проверяет загружен ли Record Manager изатем выполняет прерывание.
BTR_ERR EQU 20 BTR_VECTOR EQU 07BH*4PUSH DS
SUB BX,BX ;Очистка BX MOV DS,BX ;DS=>абсолютный 0 CMP WORD PTR BTR_VECTOR[BX],033H ;Был ли Btrieve инициализированPOP DS
JE DO_INT ;Да - переход на выполнение прерывания MOV STAT,BTR_ERR ;Нет - установка статуса 20 JMP OUT ;и возврат к вызывающей программе DO_INT: INT 07BH ;Вызов Record Manager
ИНТЕРФЕЙС OS/2
NetWare Btrieve включает два интерфейса для C-компилятора OS/2 (C2XBTRV.C и C2FXBTRV.C), которые Вы можете подключать к прикладным прогаммам, запускаемым на рабочих станциях OS/2. Интерфейс C2XBTRV.C - для применения с прикладными программами в защищенном режиме. Интерфейс C2FXBTRV.C - для применения с программами OS/2 FAPI.
Если Вы используете язык, который может вызывать программу на ассемблере, Вы можете написать на ассемблере интерфейс с Btrieve, используя как руководство любой исходный текст интерфейса. Следующий раздел содержит руководство по применению интерфейса C и создания своего собственного интерфейса на ассемблере.
ЯЗЫК C
Если Вы применяете C-компилятор, поставляемые с OS/2, Вы имеете две опции:
- Вы можете компилировать или C2XBTRV.C или C2FXBTRV.C интерфейс отдельно от Вашей программы. Или подключайте результирующие объектные модули, когда Вы компануете Ваши программы, или инсталируйте объектную программу в библиотечный файл, который Вы можете подключать к Вашему редактору связей.
- Вы можете подключать исходную программу интерфейса, содержащуюся или в C2XBTRV.C или в C2FXBTRV.C, к исходному тексту Вашей прикладной программы при компиляции Вашей программы.
ЯЗЫК АССЕМБЛЕР
Если вы используете ассемблер, Ваша прикладная программа должна применять механизм динамической компановки OS/2 для получения доступа к Btrieve-программам. Пользуйтесь следующим руководством при создании интерфейса на ассемблере для OS/2:
- Посылайте все параметры в стек.
- Используйте регистр AX для получения кода возвраиа из
Btrieve.
- Используйте форму selector:offset (селектор:смещение) для всех адресов интерфейса.
- Используйте FAR CALL для доступа к программе редактора динамических связей.
- Не извлекайте возвращаемые параметры из стека.
- Задавайте имя программы редактора динамческих связей символами верхнего регистра.
КОМПАНОВКА ПРИКЛАДНЫХ ПРОГРАММ OS/2
Внешние ссылки к программам редактора динамических связей одинаково разрешены и для C и для ассемблера.
Вы должны обеспечить редактору связей библиотеку BTRCALLS.LIB при компановке Ваших объектных файлов. Библиотека содержит записи-определения динамических связей, обеспечивающих соответствие между вызываемой программой и файлом BTRCALLS.DLL. если редактор связей не имеет доступа к BTRCALLS.LIB, он сообщит о недопустимой компановке для точек входа редактора динамических связей.
ПРИМЕЧАНИЕ:
Для домашних прикладных программ Вы должны использовать интерфейс C2FXBTRV.C, скомпоновать Вашу прикладную программу и затем запустить утилиту OS/2 BIND. Программа BUTIL.EXE - пример прикладной программы FAPI. -----------------------------------------------------------
ИНТЕРФЕЙС С BROUTER
Если Вы создаете VAP, использующий Btrieve-файлы, Вы должны подключить интерфейс с BROUTER к Вашей программе. Следуйте процедурам, описанным в разделе "Связь Btrieve с ассемблером" со следующими дополнениями:
- Запрашивайте вызов функции "Get Interrupt Vector" для определения, загружен ли BROUTER.
- Сохраните уникальный номер ID клиента в регистре AX до выполнения прерывания 7B.
- Идентифицируйте каждую рабочую станцию, имеющую доступ к
Вашему VAP, уникальным 2-байтовым номером ID клиента. Вы должны обеспечить этот номер для BROUTER для целей процессов парралелизма и транзакций. Удобный метод для создания номера ID клиента - сохранение номера связи рабочей станции в первом байте и уникальное двоичное значение во втором байте.
- Идентифицируйте Ваш VAP в BROUTER, используя уникальный 2-сивол, ASCII идентификатор в регистре BX. Этот идентификатор отличает Ваш VAP от всех других VAP, имеющих доступ к BROUTER. Свяжитесь с Novell Development Products Division, чтобы получить идентификатор для Вашего VAP. Адрес Novell Development Products Division:
Novell Development Products Division 6034 West Courtyard Suite 220 Austin, TX 78730
Обычно Ваш интерфейс с BROUTER должен выполнить все следующие шаги:
- Проверить, загружен ли BROUTER, с помощью выполнения обращения к функции "Get Interrupt Vector".
- Сохранить блок Btrieve-параметров в памяти в формате, ожидаемом Record Manager.
- Сохранить адрес блока Btrieve-параметров в регистре DX.
- Сохранить номер ID клиента, который является уникальным для каждой рабочей станции, в регистре AX.
- Сохранить уникальный 2-символ, ASCII идентификатор для VAP, в регистре BX.
- Выполнить прерывание 7B, которое передает управление из Вашего VAP в BROUTER.
| <<
| <
| >
| >>
|
Содержание
|