Application Building Guide


C++ Considerations for UDFs and Stored Procedures

Function names can be 'overloaded' in C++. Two functions with the same name can coexist if they have different arguments, as in:

   int func( int i )

and

   int func( char c )

C++ compilers 'type-decorate' or 'mangle' function names by default. This means that argument type names are appended to their function names to resolve them, as in func__Fi and func__Fc for the two earlier examples. The mangled names will be different on each platform, so code that explicitly uses a mangled name is not portable.

On OS/2 and Windows 32-bit operating systems, the type-decorated function name can be determined from the .obj (object) file.

With the VisualAge C++ compiler on OS/2 and Windows, you can use the cppfilt command to determine the type-decorated function name from the .obj (object) file, as follows:

   cppfilt -b /p myprog.obj

where myprog.obj is your program object file.

With the Microsoft Visual C++ compiler on Windows, you can use the dumpbin command to determine the type-decorated function name from the .obj (object) file, as follows:

   dumpbin /symbols myprog.obj

where myprog.obj is your program object file.

On UNIX platforms, the type-decorated function name can be determined from the .o (object) file, or from the shared library, using the nm command. This command can produce considerable output, so we suggest you pipe the output through grep to look for the right line, as follows:

   nm myprog.o | grep myfunc

where myprog.o is your program object file, and myfunc is the function in the program source file.

The output produced by all of these commands includes a line with the mangled function name. On UNIX, for example, this line is similar to the following:

   myfunc__FPlT1PsT3PcN35|     3792|unamex|         | ...

Once you have obtained the mangled function name from one of the above commands, you can use it in the appropriate command. We demonstrate this below using the mangled function name obtained from the UNIX example above. A mangled function name obtained on OS/2 or Windows would be used the same way.

When registering a UDF with CREATE FUNCTION, the EXTERNAL NAME clause must specify the mangled function name:

   CREATE FUNCTION myfunco(...) RETURNS...
          ...
          EXTERNAL NAME '/whatever/path/myprog!myfunc__FPlT1PsT3PcN35'
          ...

Likewise, when calling a stored procedure, the CALL function must also specify the mangled function name:

   CALL 'myprog!myfunc__FPlT1PsT3PcN35' ( ... )

If your stored procedure or UDF library does not contain overloaded C++ function names, you have the option of using extern "C" to force the compiler to not type-decorate function names. (Note that you can always overload the SQL function names given to UDFs, since DB2 resolves what library function to call based on the name and the parameters it takes.)



#include <string.h>
#include <stdlib.h>
#include "sqludf.h"
 
/*---------------------------------------------------------------------*/
/* function fold: output = input string is folded at point indicated   */
/*                         by the second argument.                     */
/*         inputs: CLOB,                 input string                  */
/*                 LONG                  position to fold on           */
/*         output: CLOB                  folded string                 */
/*---------------------------------------------------------------------*/
extern "C" void fold(
      SQLUDF_CLOB       *in1,                    /* input CLOB to fold       */
   ...
   ...
}
/* end of UDF: fold */
 
/*---------------------------------------------------------------------*/
/* function find_vowel:                                                */
/*             returns the position of the first vowel.                */
/*             returns error if no vowel.                              */
/*             defined as NOT NULL CALL                                */
/*         inputs: VARCHAR(500)                                        */
/*         output: INTEGER                                             */
/*---------------------------------------------------------------------*/
extern "C" void findvwl(
      SQLUDF_VARCHAR    *in,                     /* input smallint           */
   ...
   ...
}
/* end of UDF: findvwl */

In this example, the UDFs fold and findvwl are not type-decorated by the compiler, and should be registered in the CREATE FUNCTION statement using their plain names. Similarly, if a C++ stored procedure is coded with extern "C", its undecorated function name would be used in the CALL statement.


[ Top of Page | Previous Page | Next Page ]