Subject Re: UDF Assistance
Author mgdew_123
Thanks Ivan.

Does the FREE_IT need to be declared for IB5.6, IB 6.2 aswell ? I have
a mixture of versions out there at present and need it to work with
them all.

unit OwlUDF;

interface

uses
SysUtils, Classes, ib_util;

function OWL_LEFT(Str: PChar; var Count: integer): PChar; cdecl; export;
function OWL_LEFTMAX256(Str: PChar; var Count: integer): PChar; cdecl;
export;

implementation

//##################################################################################################
// Returns a substr of another string starting at Index and Count
characters long
//##################################################################################################
function OWL_LEFT(Str: PChar; var Count: integer): PChar;
//##################################################################################################
var
s: PChar;
i: integer;
begin
if (Str = nil) then
Result := nil
else begin
s := PChar(Copy(string(Str), 0, Count));
i := StrLen(PChar(s)) + 1;
Result := ib_util_malloc(i);
if (PChar(s) = nil) or (i = 1) then
result[0] := #0
else
Move(s^, Result^, i);
end;

end;

//##################################################################################################
// Returns a substr of another string starting at Index and Count
characters long
//##################################################################################################
function OWL_LEFTMAX256(Str: PChar; var Count: integer): PChar;
//##################################################################################################
var
s: PChar;
i: integer;
j: integer;
begin
if (Str = nil) then
Result := nil
else begin
if Count >= 256 then
j := 255
else
j := Count;
s := PChar(Copy(string(Str), 0, j));
i := StrLen(PChar(s)) + 1;
Result := ib_util_malloc(i);
if (PChar(s) = nil) or (i = 1) then
result[0] := #0
else
Move(s^, Result^, i);
end;

end;

end.


This is my new compiled dll. I have declared the functions inside an
IB6 database and they work well. I have tried to declare them and use
them in an IB 5.6 database, they are accepted fine but when using them
I get an error saying not declared or entry point not found ? do I
have to backup and restore the databse before it can use the new udf's ?





--- In firebird-support@yahoogroups.com, "Ivan Prenosil"
<Ivan.Prenosil@s...> wrote:
> String returned by your UDF must be allocated using this function
>
> function ib_util_malloc(size: LongWord): Pointer; external
'ib_util.dll';
>
> and you have to instruct Firebird to release the memory using
FREE_IT keyword:
>
> ... RETURNS CSTRING(100) FREE_IT ...
>
>
> Ivan
> http://www.volny.cz/iprenosil/interbase/
>
> ----- Original Message -----
> From: "Martin Dew" <martin.dew@a...>
> To: <firebird-support@yahoogroups.com>
> Sent: Wednesday, January 05, 2005 2:17 PM
> Subject: [firebird-support] UDF Assistance
>
>
> >
> > I basically have some VARCHAR(8192) fields which I only want to
return a
> > maximum of 100 characters from them (large Data to fetch on some
> > queries) ..
> >
> > I have written a UDF in Delphi ( library and Unit file below ) to do
> > this through a function called OWL_STRLEFT100.
> >
> > I have declared it using;
> >
> > declare external function OWL_STRLEFT100
> > CSTRING(8192) CHARACTER SET NONE,
> > integer
> > returns
> > CSTRING(100) CHARACTER SET NONE
> > entry_point 'OWL_STRLEFT100' module_name 'OwlUDFs.dll';
> >
> >
> > however, when I try to run it say for example;
> >
> > select OWL_STRLEFT100(symptoms,1) from sp_patlogview
> >
> > It crashes the connection (error message "Connection lost to
database").
> >
> > I am assuming I have done something wrong here, could anyone help
me out
> > and point out the errors of my ways ?
> >
> > Thanks in advance.
> > Martin
> >
> > -----
> >
> > library OwlUDFs;
> >
> > { Important note about DLL memory management: ShareMem must be the
> > first unit in your library's USES clause AND your project's (select
> > Project-View Source) USES clause if your DLL exports any
procedures or
> > functions that pass strings as parameters or function results. This
> > applies to all strings passed to and from your DLL--even those that
> > are nested in records and classes. ShareMem is the interface unit to
> > the BORLNDMM.DLL shared memory manager, which must be deployed along
> > with your DLL. To avoid using BORLNDMM.DLL, pass string information
> > using PChar or ShortString parameters. }
> >
> > uses
> > SysUtils,
> > Classes,
> > OwlUDF in 'OwlUDF.pas';
> >
> > {$R *.RES}
> >
> > exports
> > OWL_STRLEFT100;
> >
> > begin
> > end.
> >
> >
> > -----
> >
> >
> > unit OwlUDF;
> >
> > interface
> >
> > function OWL_STRLEFT100(var sz: PChar; var cnt: Integer): PChar;
> > cdecl; export;
> >
> > implementation
> >
> > function OWL_STRLEFT100(var sz: PChar; var cnt: Integer): PChar;
> > Var
> > i : integer;
> > s : String;
> > begin
> > if (sz = nil) then begin
> > result := nil
> > end
> > else if (cnt = 0) then begin
> > result := nil
> > end
> > else begin
> > if (cnt >= 100) then
> > i := 99
> > else
> > i := cnt;
> >
> > s := copy(sz,0,i);
> > result := PChar(s);
> > end;
> > end;
> >
> > end.