< Google API 文字化け続報 | sanitize属性 >

February 25, 2004

VC++でDLLを作る

VC++でDLLを作るときのポイントです。

DLLを作る

DLL内では、Exportする関数に

extern "C" __declspec (dllexport)
をつける。これらをまとめて
#define DllExport extern "C" __declspec (dllexport)
としておくとよい。 extern "C" が必要になるのはC++のときのみ。 以下のように分岐する方法もある。
#ifdef MYDLL 
#define DECLSPEC_DLLPORT	__declspec(dllexport)
#else
#define DECLSPEC_DLLPORT	__declspec(dllimport)
#endif

#ifdef __cplusplus
extern "C"{
#endif

DECLSPEC_DLLPORT void func();

#ifdef __cplusplus
}
#endif
DLLの初期化や終了の際にはDllMainが呼ばれる。
BOOL WINAPI DllMain( HANDLE hInstance, ULONG What, LPVOID NotUsed );
Whatは以下の値。
DLL_PROCESS_ATTACH
DLL_PROCESS_DETACH
DLL_THREAD_ATTACH
DLL_THREAD_DETACH
非ゼロを返さないと呼び出し側ではエラーとなってしまう。 逆にエラー時には0を返す。

静的にリンクする

DLLを使う側では、インポートライブラリ(.libファイル)をリンクして、

extern "C" __declspec (dllimport)
をつけたプロトタイプを定義する。(または定義されたヘッダファイルをincludeする) これも
#define DllImport extern "C" __declspec (dllimport)
のようにしておく。 あとは普通の関数と同じにコールできる。

動的にリンクする

HMODULE LoadLibrary( LPCSTR DllName );
で、DLLの名前を指定してハンドルを取得する。
FARPROC GetProcAddress( HMODULE hMod, LPCSTR FuncName );
で、関数名を指定して、関数ポインタを取得する。 たとえば、DLL側で
int MyFunc( int a, int b );
と定義されているなら
int ( *f )( int, int );
f	= ( int (*)( int, int ) )GetProcAddress( hLib, "MyFunc" );	// 実際の関数の型にキャスト
ret	= (*f)( a, b );	// 呼び出す
最後に
BOOL FreeLibrary( HMODULE hMod );
で、DLLの参照カウントを解放する。

トラックバック

このエントリーにトラックバック:
http://frog.raindrop.jp/cgi-bin/mt/mt-tb.cgi/203

コメント

Sorry, comment closed.