SAK 図書館
VS.NET C 言語編2 - win32 DLL、__declspec(dllexport)、DllExport、.def
■VC.NET で DLL 作成 ・むむむっ、昔のお約束とかなり違うぞ。(^^; _export FAR PASCAL が恋しい。(^◇^;) ・DLL は、関数名に大文字小文字の区別をなくし(内部的に大文字固定)、 引数スタックを C 標準とは逆の VB や PASCAL 規約の順にするはず。 WINAPI = FAR PASCAL なので、引数の順序は WINAPI を使用している限り 問題ない。 ところが、関数名がどうやっても大文字小文字の区別が付いてしまう。 .def で大文字固定にすると、今度は VB が区別している... 私の思い違いなんだろうか... 昔から区別ってあったかな? (^^; ・DLL 関数のエクスポートは、_export が古い書式と怒られてしまう。 __declspec(dllexport) でエクスポートするのが最近のお約束らしい。 #define DllExport __declspec(dllexport) を使用することにした。 ・ヘルプでは、なつかしのモジュール定義ファイル(.def) を使用しなくても OK と書いてあるのだが、C 言語の内部関数名的にエクスポートされてしま う。(_TestFnc@8 とかってやつね。) 私は、Borland C 派だったもので、.def でエクスポート定義なんかしたこ とない。ヘルプ調べまくって書式がわかった。 「エクスポート名 = オリジナル名」である。 次の例は、一見同じことに見えるのだが、これを指定すると、 「TestFnc = _TestFnc@8」と変換される。 DEF ファイルを作成しなければ、VB では、とっても使いにくい DLL になる。 LIBRARY Test EXPORTS TestFnc = TestFnc ・【追加情報】 「extern "C" __declspec(dllexport)」とすると、 関数名が C++ ではなく、C の命名規則でエクスポートされ、DEF ファイル を不要にできるらしい。 どうやら、「@」以降の部分は "引数が違うが同名" である関数の衝突を 避けるためのもので、C++ 以降の仕様とのこと。 (情報下さった方、ありがとうございます。) ・【追加情報2】 win16 のときは #define PASCAL __pascal だったが、 win32 では #define PASCAL __stdcall となっている。 __pascal は関数名を全て大文字にするが、__stdcall はそのまま。 但し、関数名に(C++ かどうかにかかわらず) @8 のようなのが付く。 (@ の後に数字が並ぶものは __stdcall、そうでないものは C++ の名前修飾 によるもの) 今の VB も __stdcall を使っているとのこと。 (情報下さった方、ありがとうございます。) ■DLL テスト(win32 ダイナミックリンクライブラリ) ・VC.NET で、C++ ではなく、C をコンパイルする場合、プリコンパイルヘッダ を使用しないようにしないと、コンパイラが正しく動作しない。 /* ======================================================================== DLL テスト(win32 ダイナミックリンクライブラリ) ======================================================================== */ // インクルードヘッダ #include <windows.h> // 定数宣言 #define DllExport __declspec(dllexport) // 関数プロトタイプ DllExport LONG WINAPI TestFnc(LONG a, LONG b); /* ======================================================================== メイン ======================================================================== */ BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } /* ======================================================================== テスト関数 ======================================================================== */ DllExport LONG WINAPI TestFnc(LONG a, LONG b) { LONG c; // 加算 c = a + b; // リターン return c; } ■パソコン基礎知識 C 言語編資料
■プログラミング言語資料
■パソコン基礎知識 ハード編資料
■パソコン基礎知識 画像編資料
■パソコン基礎知識 Windows 編資料
■コンピュータシステム導入編資料