Subject Re: creating and declaring a UDF that returns a string
Author chris.waldmann
--- In firebird-support@yahoogroups.com, "samcarleton" <scarleton@...> wrote:
>
> I have written a simple UDF to get the time as a string from a timestamp, returning '00:00:00' if no valid input was given. There seems to be a problem when calling the UDF, the server crashes. This is the only UDF I have ever created that allocates memory and returns said memory to the database, so I am figuring either the declaration of the UDF is wrong or the C code itself is wrong. Here is what I have:
>
> DECLARE EXTERNAL FUNCTION TRUNK_TIMESTAMP_TO_TIME
> DATE
> RETURNS CSTRING(8) FREE_IT
> ENTRY_POINT 'fn_timestr' MODULE_NAME 'my_udf';
>
> -------------------------------------------------
>
> char* EXPORT fn_timestr (ARG(ISC_TIMESTAMP*, ts))
> ARGLIST(struct ISC_TIMESTAMP* ts)
> {
> short bufByteSize = sizeof(char) * 9;
> char *datebuf = (char *)malloc(bufByteSize);
>
> struct tm tm_src;
>
> if(ts && (ts->timestamp_date || ts->timestamp_time))
> {
> isc_decode_timestamp(ts, &tm_src);
> strftime(datebuf, bufByteSize, "%H:%M:%S", &tm_src);
> }
> else
> {
> strcpy(datebuf, "00:00:00");
> }
>
> return datebuf;
> }
>

You must use the 'firebird' malloc. Here is a snippet of one of my UDFs:

#include "ib_util.h"

// interface to get RFID ascii text from FireBird Database UDF
//
// Param: 64 bit int (BIGINT, INT64)
// return: CHAR( BUFFER_LEN-1 )
//
char * __DLL_TYPE _stdcall getRfIdChar( __int64 * rfId ){
char * buffer = ib_util_malloc( BUFFER_LEN );

getRfIdText( *rfId, buffer );
return buffer;
}

Good luck
Christian