3

I tried to create a simple user defined function (UDF) for Firebird 2.5 with C++ Builder 2010 but I don't manage to get it to work in Firebird.

  1. Creating a DLL project with default setting in C++ Builder 2010.
  2. Adding a unit with my example UDF including "ibase.h" and "ib_util.h":

    extern "C" __declspec(dllexport) int __stdcall MYFUNC ( int i )  
    {  
         int result = 2 * i;  
         return result;  
    }  
    
  3. Building the DLL FBUDFMBD.dll in path C:\Program Files (x86)\Firebird\Firebird_2_5\UDF

  4. Registering my UDF via IBExpert in a sample db with

    DECLARE EXTERNAL FUNCTION F_MYFUNC  
    INTEGER  
    RETURNS INTEGER 
    ENTRY_POINT 'MYFUNC' MODULE_NAME 'FBUDFMBD';
    
  5. Calling the UDF with

    select F_MYFUNC( 3 ) from RDB$DATABASE;
    

    results in error message

    Invalid token.  
    invalid request BLR at offset 36.  
    function F_MYFUNC is not defined.  
    module name or entrypoint could not be found.
    

With the tool GExperts - PE Information I can see my UDF as DLL-Export MYFUNC ordinal $1 and entry point $1538.

What I am doing wrong, Firebird can't register my DLL and its UDF correctly?

Is there anything in my DLL project to change regarding to default compiler options?

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Bernd E.
  • 51
  • 5
  • In my experience Firebird UDF question - usually - don't get a lot of answers here; you might want to consider asking your question on the Firebird-support mailinglist as well. – Mark Rotteveel Jul 21 '16 at 17:21
  • I'm not 100% sure, but I believe you need to remove the `extern "C" __declspec(dllexport)`, look for an example at https://github.com/FirebirdSQL/firebird/blob/8905e15435116bfac3abb30ae476d4812d1fe04b/src/extlib/ib_udf.cpp – Mark Rotteveel Jul 21 '16 at 17:39

2 Answers2

2

In Delphi, you can write cdecl and not stdcall

i.e

function ExisteBase(const aBase:PChar):Integer; cdecl;

Not

function ExisteBase(const aBase:PChar):Integer; stdcall;

Maybe on C++ __cdecl

I hope I helped in some

manlio
  • 18,345
  • 14
  • 76
  • 126
Mario Ruiz
  • 23
  • 4
2

Thanks a lot! I got it by your help.

top 2: Corrected C++-Code is:

extern "C" __declspec(dllexport) int MYFUNC ( int * val )
{
   int result = 2 * *val;
   return result;
}

Pay attention to reference call of the input parameter.

top 4: Register the UDF in a firebird 2.5 db by

DECLARE EXTERNAL FUNCTION F_MYFUNC
INTEGER
RETURNS INTEGER BY VALUE
ENTRY_POINT '_MYFUNC' MODULE_NAME 'FBUDFMBD';

Pay attention to the leading underscore at the function name!

top 5: select F_MYFUNC( 3 ) from RDB$DATABASE; works really fine!

Bernd E.
  • 51
  • 5