(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 !!)