DLL 関数の Visual Basic アプリケーションからの呼び出し方

VBA (Visual Basic アプリケーション) や Pascal、Fortran などの他の言語で書かれたアプリケーションから C/C++ DLL 内の関数を呼び出すには、コンパイラによって装飾された名前ではなく正しい呼び出し規約を使ってその関数をエクスポートする必要があります。

__stdcall は、関数の正しい呼び出し規約を作成します。つまり、呼び出された関数がスタックをクリアし、パラメーターは右から左へ渡されます。ただし、関数名は異なる方法で装飾されます。 このため、__declspec(dllexport) が DLL 内のエクスポート関数で使用される場合は、装飾名がエクスポートされます。

__stdcall 方式で装飾された名前には、シンボル名の前に _ (アンダースコア)、シンボルの後に @ (アット マーク) が付けられ、その後に引数リストのバイト数 (必要なスタック空間) が付けられます。 結果として、宣言時の関数は次のようになります。

int __stdcall func (int a, double b)

これを装飾すると、次のようになります。

_func@12

C の呼び出し規約 (__cdecl) による装飾では、名前は _func となります。

装飾名を取得するには、/MAP を使用します。 __declspec(dllexport) を使うと、以下の処理が行われます。

  • 関数が C の呼び出し規約 (_cdecl) に従ってエクスポートされる場合、先頭のアンダースコア (_) は名前のエクスポート時に除去されます。

  • エクスポートされる関数が C の呼び出し規約を使わない場合 (__stdcall など) は、装飾名がエクスポートされます。

スタックがクリアされた場所をオーバーライドする方法はないので、__stdcall を使う必要があります。 __stdcall を使って装飾を外すには、.def ファイルの EXPORTS セクションにエイリアスを使って、その名前を指定する必要があります。 関数宣言の例を次に示します。

int  __stdcall MyFunc (int a, double b);
void __stdcall InitCode (void);

.DEF ファイルの内容は、次のとおりです。

EXPORTS
   MYFUNC=_MyFunc@12
   INITCODE=_InitCode@0

Visual Basic で書かれたプログラムから DLL を呼び出す場合は、ここで示したエイリアスの手法を .def ファイル内で使用する必要があります。 エイリアスが Visual Basic プログラムの中で宣言されている場合は、.def ファイル内でのエイリアスは不要です。 Visual Basic プログラムでは、Declare ステートメントにエイリアス句を追加することで実現されます。

さらに詳しくは次のトピックをクリックしてください

参照

概念

DLL