王朝网络
分享
 
 
 

[UDF系列]如何编写InterBase UDF 之二

王朝other·作者佚名  2006-01-08
宽屏版  字体: |||超大  

(接上一篇)

如何编写InterBase UDF

warton译

怎么编写字符串和日期型处理函数的UDF呢?

下面编写一个“Left“函数

内存分配问题:

如果你使用IB(InterBase)5.1以下版本的话,在你的单元文件中键入下面的声明:

function malloc(Bytes: Integer): Pointer; cdecl; external 'msvcrt.dll';

如果你有5.5以上的版本,你就不需要这么做了。这样,先确定ib_util.pas 文件在你的编译器可以找到的路径中,并且ib_util.dll也在你的搜索路径之中。

最简单的方法是放到的库可搜索到的路径。

c:\Program Files\InterBase Corp\InterBase\include

然后复制

c:\Program Files\InterBase Corp\InterBase\lib\ib_util.dll

到你的windows系统目录下(典型的是:c:\Windows\System)。最后在你的单元文件的use子句中将ib_util.pas加进去

uses

...,

ib_util;

为什么有如此奇特的内存分配?为什么我不能用AllocMem分配内存,或者其它方法?问题很简单:你不能,所以不要问!更复杂的问题是每一个编译器使用它喜欢的算法来进行内存管理,这是被操作系统控制着的。例如,VC和Delphi管理内存的方式不同,猜这是为什么?IB是在VC下编译的,在5.5以前的版本中,你必须直接指定运行库。在IB5.5之后,IB给了一个IB调用使得这成为可能。既然这样,那我们继续进行编写字符串操作的函数。

构建函数

在新的单元文件中,作如下声明:

function Left(sz: PChar; Cnt: Integer): PChar; cdecl; export;

在函数实现部分:

(* 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 < cnt)) do Inc(i);

result := ib_util_malloc(i+1);

Move(sz[0], result[0], i);

result[i] := #0;

end;

end;

在你的工程文件中,在“exports“部分键入:

exports

Modulo,

Left;

Now,再次编译工程项目….

现在,为了使用函数,在ISQL中重新连接数据库,输入:

declare external function f_Left

cstring(64), integer

returns cstring(64) free_it

entry_point 'Left' module_name 'dll name minus ".dll"';

测试这个函...

select f_Left('Hello', 3) from rdb$database

仍然相当简单,哈?

上我们来编写一个时间函数

在IB6中,有三种不同的时期类型被支持,DATE,TIME,和TIMESTAMP,与IB5.5及以前老版本中的相比,TIMESTAMP 的数据类型实质上相当于IB5.5的DATE类型。

为了在你的程序中”decode”和”encode”这些类型。你应该了解一点IB API相关的信息。输入以下代码:

interface

...

type

TM = 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 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;

现在我们写日期UDF:

在单元文件的interface部分,输入声明:

function Year(var ib_date: Long): Integer; cdecl; export;

function Hour(var ib_time: ULong): Integer; cdecl; export;

在implementation(实现)部分,输入:

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;

最好,在你的工程文件中:在““部分,输入:

exports

Modulo,

Left,

Year,

Hour;

现在编译工程...

为了使用这个函数,就像上面那样:用ISQL连接数据库,输入:

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"';

最后再测试一下看!

select f_Year(cast('7/11/00' as date)) from rdb$database

这一部分并非像前面字符串和整数那样操作哪样了,但是还是相当...simple,哼!

编写Linux/Unix平台的UDF

(未完待续!!)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有