打印本文 打印本文 关闭窗口 关闭窗口
如何编写InterBaseUDF之二
作者:武汉SEO闵涛  文章来源:敏韬网  点击数1302  更新时间:2009/4/22 23:21:49  文章录入:mintao  责任编辑:mintao

(接上一篇)

如何编写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

[1] [2]  下一页

打印本文 打印本文 关闭窗口 关闭窗口