[UDF series] How to write two Interbase UDF

zhaozj2021-02-16  64

(Connected to the previous one)

How to write Interbase UDF

Warton translation

How do you write a string and a date-dated UDF?

The following is written in a "left" function

Memory allocation problem:

If you use IB (Interbase) 5.1: Type the following declaration in your unit file:

Function malloc (bytes: integer): Pointer; cdecl; external 'msvcrt.dll';

If you have a version of 5.5 or more, you don't need to do this. This way, first determine that IB_UTIL.PAS files can be found in your compiler, and IB_UTIL.DLL is also in your search path.

The simplest method is the path to which the library can be searched.

C: / Program Files / Interbase Corp / Interbase / Include

Then copy

C: / program files / interbase corp / interbase / lib / ib_util.dll

Under your Windows system directory (typical: c: / windows / system). Finally, add IB_UTIL.PAS in the USE clause of your unit file.

Uses

...,

IB_UTIL;

Why is there such a strange memory allocation? Why can't I assign memory with allocmem, or other methods? The problem is very simple: you can't, so don't ask! More complex issues is that each compiler uses its favorite algorithm to perform memory management, which is controlled by the operating system. For example, VC and Delphi manages memory different ways, guess why? IB is compiled under VC, in the previous version of 5.5, you must specify the run library directly. After IB5.5, IB gives an IB call make it possible. Since this, let's continue to write a function of string operations.

Build function

In the new unit file, make the following statement:

Function Left (SZ: PCHAR; CNT: Integer): PCHAR; CDECL;

Implement part of the function:

(* Return The CNT Leftmost Characters of Sz *)

Function Left (SZ: PCHAR; VAR CNT: Integer): PCHAR;

VAR

i: integer;

Begin

IF (sz = nil) THEN

Result: = NIL

Else Begin

I: = 0;

WHILE ((SZ [i] <> # 0) AND (i

Result: = IB_UTIL_MALLOC (i 1);

Move (SZ [0], Result [0], i);

Result [I]: = # 0;

END;

END;

In your project file, type in the "exports" section:

Exports

MODULO,

LEFT;

NOW, compile the project again ...

Now, in order to use the function, reconnect the database in ISQL, enter:

Declare External Function F_LEFT

CSTRING (64), INTEGER

Returns CString (64) Free_IT

Entry_Point 'Left' Module_name 'DLL Name Minus ".dll"';

Test this letter ...

SELECT F_LEFT ('Hello', 3) from RDB $ DATABASE

Still quite simple, ha?

Let's write a time function in IB6, three different period types are supported, Date, Time, and TimeStamp, compared to IB5.5 and previous versions, TimeStamp data types are essentially equivalent to IB5. 5 Date type.

In order to "decode" and "eNCode" in your program. You should learn about the IB API related information. Enter the following code:

Interface

...

Type

TM = Record

TM_SEC: Integer; // Seconds

TM_MIN: INTEGER; // minutes

TM_HOUR: INTEGER; // Hour (0--23)

TM_MDAY: INTEGER; // days of Month (1--31)

TM_MON: INTEGER; // Month (0--11)

TM_Year: Integer; // Year (Calendar Year Minus 1900)

TM_WDAY: Integer; // Weekday (0--6) Sunday = 0)

TM_YDAY: INTEGER; // day of year (0--365)

TM_ISDST: Integer; // 0 if Daylight Savings Time Is Not in Effect)

END;

PTM = ^ Tm;

ISC_TimeStamp = Record

TimeStamp_Date: long;

TimeStamp_Time: Ulong;

END;

PISC_TimeStamp = ^ ISC_TimeSTAMP;

IMPLEMENTATION

...

Procedure isc_encode_timestamp (tm_date: PTM;

IB_DATE: PISC_TIMESTAMP);

STDCALL; EXTERNAL IBASE_DLL;

Procedure isc_decode_timestamp (ib_date: pisc_timestamp;

TM_DATE: PTM);

STDCALL; EXTERNAL IBASE_DLL;

Procedure isc_decode_sql_date (var ib_date: long;

TM_DATE: PTM);

STDCALL; EXTERNAL IBASE_DLL;

Procedure isc_encode_sql_date (TM_DATE: PTM;

VAR IB_DATE: Long);

STDCALL; EXTERNAL IBASE_DLL;

Procedure isc_decode_sql_time (var ib_date: ulong;

TM_DATE: PTM);

STDCALL; EXTERNAL IBASE_DLL;

Procedure isc_encode_sql_time (tm_date: PTM;

VAR IB_DATE: ULONG);

STDCALL; EXTERNAL IBASE_DLL;

Now we write the date UDF:

In the Interface section of the unit file, enter the statement:

Function year (var ib_date: long): integer; cdecl; export;

Function Hour (var ib_time: ulong): integer; cdecl; export;

In the IMPLEMENTITION section, enter:

Function Year (var ib_date: long): integer;

VAR

TM_DATE: TM;

Begin

ISC_DECode_sql_date (@IB_date, @TM_DATE); Result: = Tm_Date.tm_Year 1900;

END;

Function Hour (var ib_time: ulong): Integer;

VAR

TM_DATE: TM;

Begin

ISC_Decode_sql_time (@Ib_time, @TM_DATE);

Result: = tm_date.tm_Hour;

END;

Best, in your project file: in "" section, enter:

Exports

MODULO,

LEFT,

Year,

Hour;

Compile work now ...

In order to use this function, just like the above: Connect the database with the ISQL, enter:

Declare External Function F_Year

date

Returns Integer by Value

Entry_Point 'Year' Module_name 'DLL Name Minus ".dll"';

DECLARE EXTERNAL FUNCTION F_HOUR

Time

Returns Integer by Value

Entry_Point 'Hour' Module_name 'DLL Name Minus ".dll"';

Finally, test it!

SELECT F_YAREAR (Cast ('7/11/00' as date) from RDB $ Database

This part does not operate like the previous string and integers, but it is quite ... Simple, Hey!

Write the UDF of the Linux / UNIX platform

(Until you have ended !!)

转载请注明原文地址:https://www.9cbs.com/read-26652.html

New Post(0)