Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
управление данными 2.doc
Скачиваний:
14
Добавлен:
07.11.2018
Размер:
2.08 Mб
Скачать

10.4.2. Создание динамической библиотеки с udf

Ниже приведен пример библиотеки и модуля с тремя UDF:

  1. // файл LibUDF.dpr с текстом библиотеки для Delphi 7: library LibUDF; uses ExtFunct in 'ExtFunct.pas';

  2. Exports

  3. IsDate index 1 name 'ISDATE',

  4. IBDateToStr index 2 name 'IBDATETOSTR',

  5. RoundFloat index 3 name 'ROUNDFLOAT';

  6. end.

// файл ExtFunct.pas с текстом модуля для Delphi 7:

unit ExtFunct;

Interface

uses SysUtils;

type

PIBDateTime = ^TIBDateTime;

TIBDateTime = record

Date: Integer;

Time: Integer;

end;

function IsDate(var InputDate: TIBDateTime): PIBDateTime;

cdecl;

function IBDateToStr(var InputDate: TIBDateTime): PChar;

cdecl;

function RoundFloat(var Value: Double; var Digits:

Integer): Double; cdecl;

procedure isc_decode_date(IBDateTime: PIBDateTime;

P: Pointer); stdcall;

implementation procedure isc_decode_date; external 'gds32.dll' name 'isc_decode_date';

var OutDate: TIBDateTime;

function IsDate(var InputDate: TIBDateTime): PIBDateTime; cdecl;

begin

// первые 4 байта в InputDate - дата,

// последние 4 байта в InputDate - время;

// достаточно обнулить данные о времени чтобы

// получить только дату.

with OutDate do

begin

Date := InputDate.Date;

Time := 0;

end;

Result := @OutDate;

end;

type PCTimeStructure = ^TCTimeStructure;

TCTimeStructure = record

tm_sec : integer; // Seconds

tm_min : integer; // Minutes

tm_hour : integer; // Hour (0--23)

tm_mday : integer; // Day of month (1--31)

tm_mon : integer; // Month (0--11)

tm_year : integer; // Year = "calendar year"-1900

tm_wday : integer; // Weekday (0--6) Sunday = 0)

tm_yday : integer; // Day of year (0--365)

tm_isdst : integer;

end;

var DateStr: string[11] = #0#0#0#0#0#0#0#0#0#0#0; function IBDateToStr(var InputDate: TIBDateTime): PChar; cdecl;

var B: TCTimeStructure;

D, M, Y, I: Integer;

begin // преобразует дату из формата InterBase. isc_decode_date(@InputDate, @B);

D := B.tm_mday;

M := B.tm_mon + 1;

Y := B.tm_year + 1900;

DateStr := Format('%2d-%2d-%4d', [D, M, Y]);

repeat

I := Pos(' ', DateStr);

if I > 0 then DateStr[I] := '0';

until I = 0;

Result := @DateStr[1];

end;

function RoundFloat(var Value: Double; var Digits: Integer): Double; cdecl;

var F: Double;

begin

F := Frac(Value);

case Digits of

1: F := Round(F*10.0)/10.0;

2: F := Round(F*100.0)/100.0;

3: F := Round(F*1000.0)/1000.0;

else

F := 0;

end;

Result := Int(Value) + F;

end;

end.

Еще один пример создания библиотеки с помощью Delphi с одной функцией пользователя:

T// Файл 'TestUDF.dpr'T для Delphi 7T:

library TestUDF;

// функция определения длины текста в строковых полях

// типов CHAR(n) и VARCHAR(n):

function LengthCharField(C: PChar): Integer; cdecl;

begin

// ищем нулевой символ, который является завершителем

// строки: Result := 0;

while (C[Result] <> #0) do

Inc(Result);

// Если бы эта функция использовалась бы только для

// полей типа VARCHAR, то больше ничего делать не

// надо было бы.

// Если поле имеет тип CHAR, то оно всегда

// дополняется до максимальной длины пробелами,

// поэтому их надо учесть:

Dec(Result);

while (Result >= 0) and (C[Result] = ' ') do

Dec(Result);

Inc(Result);

end;

exports LengthCharField name 'LENGTH_CHAR_FIELD';

end.

Чтобы получить файл с DLL-библиотекой, содержащей UDF, можно, например, ввести исходный текст библиотеки с помощью любого редактора в

файл 'TestUDF.dpr' и откомпилировать его с помощью утилиты командной строки 'dcc32.exe', введя в командной строке следующую команду:

C:\Рабочая папка>dcc32 TestUDF.dpr

В результате этой команды будет создан файл 'TestUDF.DLL', который перед использованием необходимо поместить в специальную папку 'UDF', расположенную в папке с установленным сервером Firebird 1.5.

10.4.3. Объявление функций пользователя в базе данных Синтаксис оператора объявления функции пользователя следующий: DECLARE EXTERNAL FUNCTION name

[datatype | CSTRING(int) [,

datatype | CSTRING(int) ...]]

RETURNS {datatype [BY VALUE] | CSTRING(int)} [FREE_IT] ENTRY_POINT 'entryname'

MODULE_NAME 'modulename';

Параметры, входящие в этот оператор, пояснены в табл. 5.

Таблица 5

Описание параметров оператора описания UDF

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

DECLARE EXTERNAL FUNCTION ISDATE

DATE

RETURNS DATE

ENTRY_POINT 'ISDATE' MODULE_NAME 'LIBUDF';

DECLARE EXTERNAL FUNCTION IBDATETOSTR

DATE

RETURNS CSTRING(11)

ENTRY_POINT 'IBDATETOSTR' MODULE_NAME 'LIBUDF';

DECLARE EXTERNAL FUNCTION ROUNDFLOAT

DOUBLE PRECISION, INTEGER

RETURNS DOUBLE PRECISION BY VALUE

ENTRY_POINT 'ROUNDFLOAT' MODULE_NAME 'LIBUDF';

-- функция определение длины строкового поля с

-- отбрасыванием конечных пробелов:

DECLARE EXTERNAL FUNCTION STRING_LENGTH

CSTRING(100) -- в функцию передается указатель на

-- строку, заканчивающуюся нулевым

-- символом (#0) и длина здесь должна

-- быть не меньше, чем длина поля CHAR

-- или VARCHAR

RETURNS INTEGER BY VALUE –- возврат по значению ENTRY_POINT 'LENGTH_CHAR_FIELD'

MODULE_NAME 'EducatorUDF';