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 編資料
■コンピュータシステム導入編資料