関数名は C++ では「多重定義」することが可能です。 同じ名前を持つ 2 つの関数は、引き数が違っていれば以下のような形で共存させることができます。
int func( int i )
および
int func( char c )
C++ コンパイラーはデフォルトの場合、関数名を「型装飾」する、または「マングル」します。 これはつまり、関数名の後に引き数の型名を追加してそれらを解決する、 ということです。前述の例では、func__Fi および func__Fc となります。 マングルした名前はプラットフォームによって異なるため、 マングルした名前を明示的にコード中で使用しているとそのコードの移植性は失われます。
OS/2 および Windows 32 ビット・オペレーティング・システムでは、 型修飾した関数名は .obj (オブジェクト) ファイルから判別できます。
OS/2 および Windows 上の VisualAge C++ コンパイラーでは、 以下のように、cppfilt コマンドを使って、 .obj (オブジェクト) ファイルから型修飾した関数名を判別することができます。
cppfilt -b /p myprog.obj
ここで、myprog.obj はプログラムのオブジェクト・ファイルです。
Windows 上の Microsoft Visual C++ コンパイラーでは、 以下のように、dumpbin コマンドを使って、 .obj (オブジェクト) ファイルから型修飾した関数名を判別することができます。
dumpbin /symbols myprog.obj
ここで、myprog.obj はプログラムのオブジェクト・ファイルです。
UNIX プラットフォームでは、 型修飾した関数名は、nm コマンドを使って、 .o (オブジェクト) ファイルまたは共用ライブラリーから判別することができます。 このコマンドを実行するとかなりの出力量になるため、 以下のような方法でその出力を grep にパイプ処理して、 目的の行を探し出すことをお勧めします。
nm myprog.o | grep myfunc
ここで myprog.o はプログラムのオブジェクト・ファイル、 また myfunc はプログラムのソース・ファイル中の関数です。
これらのコマンドで生成した出力には、 マングルした関数名を指定した行が含まれています。 たとえば、UNIX では、この行は以下のようになります。
myfunc__FPlT1PsT3PcN35| 3792|unamex| | ...
いったん上記のコマンドの 1 つからマングルした関数名を入手すると、 該当するコマンドでその関数名を使用することができます。 上記の UNIX 例から入手したマングルした関数名の使用法を下記に示します。 OS/2 または Windows 上で入手したマングルした関数名は、 同じ方法で使用されます。
UDF を CREATE FUNCTION、EXTERNAL NAME 文節を使って登録するときには、 以下に示すように、マングルした関数名を指定する必要があります。
CREATE FUNCTION myfunco(...) RETURNS... ... EXTERNAL NAME '/whatever/path/myprog!myfunc__FPlT1PsT3PcN35' ...
同様に、ストアード・プロシージャーの呼び出し時には、 CALL 関数はマングルした関数名も指定する必要があります。
CALL 'myprog!myfunc__FPlT1PsT3PcN35' ( ... )
使用するストアード・プロシージャーまたは UDF ライブラリーに、 多重定義した C++ 関数名が含まれていない場合は、extern "C" を使用するオプションがあり、 これを使って、関数名を型修飾しないようコンパイラーに強制します。 (UDF に指定した SQL 関数名は、常に多重定義することができます。 というのは、DB2 は、名前およびパラメーターに基づいて、 呼び出されるライブラリー関数を解決するからです。)
#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 */ |
この例では、UDF fold および findvwl は、 コンパイラーによって型修飾されません。そのままの名前を使用して、 CREATE FUNCTION ステートメントで登録すべきです。 同様に、C++ ストアード・プロシージャーを extern "C" を使ってコーディングする場合、 CALL ステートメントでは修飾しない関数名を使用します。