EXPORTS
関数またはデータのエクスポート名または序数を指定する 1 つ以上のエクスポート定義のセクションを導入します。 各定義は個別の行に指定する必要があります。
EXPORTS
definition
解説
最初の definition は、EXPORTS
キーワードと同じ行か次の行で指定できます。 .DEF ファイルには、1 つ以上の EXPORTS
ステートメントを含めることができます。
エクスポートの definition の構文は次のとおりです。
<エントリ名>[=<内部名>|<他のモジュール>.<エクスポートされる名前>] [@<序数> [NONAME] ] [ [PRIVATE] | [DATA] ]
<エントリ名> は、エクスポートする関数名または変数名です。 この項目は必須です。 エクスポートする名前が DLL 内の名前と異なる場合は、<内部名> を使用して DLL でのエクスポートの名前を指定します。 たとえば、DLL で関数 func1
をエクスポートし、呼び出し元がそれを func2
として使用する場合は、次のように指定します。
EXPORTS
func2=func1
エクスポートする名前が他のモジュールからのものである場合は、<他のモジュール>.<エクスポートされる名前> を使用して DLL でのエクスポートの名前を指定します。 たとえば、DLL で関数 other_module.func1
をエクスポートし、呼び出し元がそれを func2
として使用する場合は、次のように指定します。
EXPORTS
func2=other_module.func1
エクスポートする名前が序数でエクスポートする他のモジュールからのものである場合は、<他のモジュール>.#<序数> を使用して DLL でのエクスポートの序数を指定します。 たとえば、DLL で他のモジュールから序数 42 の関数をエクスポートし、呼び出し元がそれを func2
として使用する場合は、次のように指定します。
EXPORTS
func2=other_module.#42
MSVC コンパイラでは C++ 関数の名前の装飾が使用されるため、装飾名 <内部名> を使用するか、ソース コードで extern "C"
を使用してエクスポート関数を定義する必要があります。 コンパイラでは、__stdcall 呼び出し規則を使用する C 関数も、アンダースコア (_) プレフィックスおよびアット マーク (@) とそれに続く引数リストのバイト数 (10 進数) で構成されるサフィックスで装飾されます。
コンパイラによって生成された装飾名を検索するには、DUMPBIN ツールまたは /MAP リンカー オプションを使用します。 装飾名はコンパイラ固有です。 装飾名を .DEF ファイルにエクスポートする場合、DLL にリンクする実行可能ファイルも同じバージョンのコンパイラを使用してビルドする必要があります。 これにより、呼び出し元の装飾名は .DEF ファイルのエクスポート名と一致します。
@<序数> を使用して、関数名ではなく番号が DLL のエクスポート テーブルに格納されるように指定できます。 多くの Windows DLL で、レガシ コードをサポートするために序数がエクスポートされます。 DLL のサイズを最小限に抑えるのに役立つため、16 ビットの Windows コードでは序数を使用することが一般的でした。 レガシ サポートのために DLL のクライアントで必要な場合を除き、関数を序数でエクスポートすることはお勧めしません。 .LIB ファイルには序数と関数のマッピングが含まれているため、DLL を使用するプロジェクトでは通常と同様に関数名を使用できます。
省略可能な NONAME キーワードを使用することで、序数のみでエクスポートして、生成される DLL 内のエクスポート テーブルのサイズを縮小できます。 ただし、DLL で GetProcAddress を使用する場合は、名前が有効でないため、序数がわかっている必要があります。
省略可能なキーワード PRIVATE を使用すると、<エントリ名> は LINK によって生成されるインポート ライブラリに含まれません。 同じく LINK によって生成されるイメージ内のエクスポートには影響しません。
省略可能なキーワード DATA によって、エクスポートがコードではなくデータであることが指定されます。 次の例では、exported_global
という名前のデータ変数をエクスポートする方法を示します。
EXPORTS
exported_global DATA
定義をエクスポートするには 4 つの方法があり、それらを推奨される順序で示します。
ソース コードでの __declspec(dllexport) キーワード
.DEF ファイルでの
EXPORTS
ステートメントLINK コマンドでの /EXPORT の指定
ソース コードでの comment ディレクティブ (形式は
#pragma comment(linker, "/export: definition ")
)。 次の例では、関数宣言の前の #pragma コメント ディレクティブを示します。PlainFuncName
は関数の非装飾名であり、_PlainFuncName@4
は装飾名です。#pragma comment(linker, "/export:PlainFuncName=_PlainFuncName@4") BOOL CALLBACK PlainFuncName( Things * lpParams)
#pragma ディレクティブは、関数の非修飾名をエクスポートする必要があり、ビルドの構成 (たとえば、32 ビット ビルドか 64 ビット ビルドか) によってエクスポートが異なる場合に便利です。
同じプログラムで 4 つの方法すべてを使用できます。 エクスポートを含むプログラムが LINK によってビルドされる際に、ビルドで .EXP ファイルが使用されていない限り、インポート ライブラリも作成されます。
次に、EXPORTS セクションの例を示します。
EXPORTS
DllCanUnloadNow @1 PRIVATE
DllWindowName = WindowName DATA
DllGetClassObject @4 NONAME PRIVATE
DllRegisterServer @7
DllUnregisterServer
.DEF ファイルを使用して DLL から変数をエクスポートする場合、変数に __declspec(dllexport)
を指定する必要はありません。 ただし、DLL を使用するファイルでは、データの宣言で __declspec(dllimport)
を引き続き使用する必要があります。