C++ のタイプ修飾
C++ 関数名は、多重定義することができます。 2 つの C++ 関数が同じ名前であっても、引数が異なっているなら共存可能です。 C++ コンパイラーは、デフォルトで関数名をタイプ修飾つまり「マングル」します。 タイプ修飾関数名は、その関数名に付加される引数のタイプ名で構成されます。
C++ 関数名は、多重定義することができます。 2 つの C++ 関数が同じ名前であっても、引数が異なっているなら共存可能です。例えば、最初の
func
関数が整数タイプの引数を取り、2 番目の func
関数が文字タイプの引数を取るとします。 int func( int i )
int func( char c )
C++ コンパイラーは、デフォルトで関数名をタイプ修飾つまり「マングル」します。前記の 2 つの例の func__Fi
および func__Fc
の場合のように、引数タイプ名がその関数名に付加されます。 マングルされた名前はオペレーティング・システムごとに異なるため、マングル名を明示的に使用するコードは移植可能ではありません。Windows オペレーティング・システムでは、タイプ修飾関数名は .obj
(オブジェクト) ファイルから判別できます。
Windows 上の Microsoft Visual C++ コンパイラーでは、次のように
dumpbin
コマンドを使用して、 .obj
(オブジェクト) ファイルからタイプ修飾関数名を判別することができます。 dumpbin /symbols myprog.obj
ただし myprog.obj
はプログラム・オブジェクト・ファイルです。UNIX オペレーティング・システムでは、タイプ修飾関数名は、
nm
コマンドを使用して、 .o
(オブジェクト) ファイルまたは共有ライブラリーから判別できます。 nm コマンドは大量の出力を生成することがあるので、次のように grep
を介して出力をパイピングして正しい行を探すことをお勧めします。 nm myprog.o | grep myfunc
ただしmyprog.o
はプログラム・オブジェクト・ファイル、そして myfunc
はプログラムのソース・ファイル内の関数です。これらのコマンドで生成される出力ではすべて、マングルされた関数名の入った行が示されます。 以下の nm コマンド出力例には、マングルされた関数名が入っています。
myfunc__FPlT1PsT3PcN35| 3792|unamex| | ...
上記のコマンドのうちのいずれかでマングルされた関数名を取得し終わったら、該当するコマンド内でそれを使用することができます。
CREATE ステートメントを使用してルーチンを登録するときは、
マングルされた関数名を EXTERNAL NAME 節内に指定する必要があります。 以下の例では、マングルされた関数名を、EXTERNAL NAME 節を使用して登録しています。
CREATE FUNCTION myfunco(...) RETURNS...
...
EXTERNAL NAME '/whatever/path/myprog!myfunc__FPlT1PsT3PcN35'
...
多重定義された C++ 関数名がルーチン・ライブラリー内にはない場合、
extern "C"
を使用すれば、コンパイラーで関数名がタイプ修飾されないようにするオプションを利用できます。 UDF に付ける SQL 関数名は常に多重定義できます。
データベース・マネージャーは、関数名およびそこ指定されているパラメーターに基づいて、どのライブラリー関数を呼び出すかを解決するからです。#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 */
fold
と findvwl
という UDF はコンパイラーによってタイプ修飾されないので、それぞれの実際の名前を使用して CREATE FUNCTION ステートメントで登録する必要があります。 同様に、C++ ストアード・プロシージャーまたはメソッドが extern
"C"
でコーディングされている場合、その非修飾関数名が CREATE ステートメントで使用されます。