Создание динамической библиотеки с UDF
Ниже приведен пример библиотеки и модуля с тремя UDF: // файл LibUDF.dpr с текстом библиотеки для Delphi 7: libraryLibUDF; usesExtFunct in'ExtFunct.pas'; Exports IsDate index1 name'ISDATE', IBDateToStr index2 name'IBDATETOSTR', RoundFloat index3 name'ROUNDFLOAT'; End.
// файл ExtFunct.pas с текстом модуля для Delphi 7: unitExtFunct; Interface usesSysUtils; Type PIBDateTime = ^TIBDateTime; TIBDateTime = record Date: Integer; Time: Integer; end; functionIsDate(varInputDate: TIBDateTime): PIBDateTime; cdecl; functionIBDateToStr(varInputDate: TIBDateTime): PChar; cdecl; functionRoundFloat(varValue: Double; varDigits: Integer): Double; cdecl;
procedureisc_decode_date(IBDateTime: PIBDateTime; P: Pointer); stdcall; implementation procedureisc_decode_date; external'gds32.dll' name'isc_decode_date'; varOutDate: TIBDateTime;
functionIsDate(varInputDate: TIBDateTime): PIBDateTime; cdecl; Begin // первые 4 байта в InputDate - дата, // последние 4 байта в InputDate - время; // достаточно обнулить данные о времени чтобы // получить только дату. withOutDate do Begin Date := InputDate.Date; Time := 0; end; Result := @OutDate; end;
typePCTimeStructure = ^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; varDateStr: string[11] = #0#0#0#0#0#0#0#0#0#0#0; functionIBDateToStr(varInputDate: 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); ifI > 0 thenDateStr[I] := '0'; untilI = 0; Result := @DateStr[1]; end;
functionRoundFloat(varValue: Double; var Digits: Integer): Double; cdecl; varF: Double; Begin F := Frac(Value); caseDigits 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: libraryTestUDF; // функция определения длины текста в строковых полях // типов CHAR(n) и VARCHAR(n): functionLengthCharField(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; exportsLengthCharField 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 FUNCTIONname [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 FUNCTIONISDATE DATE RETURNS DATE ENTRY_POINT 'ISDATE' MODULE_NAME 'LIBUDF'; DECLARE EXTERNAL FUNCTIONIBDATETOSTR DATE RETURNS CSTRING(11) ENTRY_POINT 'IBDATETOSTR' MODULE_NAME 'LIBUDF'; DECLARE EXTERNAL FUNCTIONROUNDFLOAT DOUBLE PRECISION, INTEGER ©2015 arhivinfo.ru Все права принадлежат авторам размещенных материалов.
|