Tips of VC++ >
DLL >
__declspec(dllexport)を使ってエクスポート
★ 前へ戻る ★ 次へ進む ★
このドキュメントにはサンプルプログラムが含まれています。
ワークスペース
ヘッダーファイル(テキスト)
ソースファイル(テキスト)
最初に「DLL概要」と
「エクスポートとインポートとリンク」を
読むと、すんなりと理解できるでしょう。
MSDNより引用しますが、説明はこれだけで十分です。
あとはサンプルを書いてみます。
__declspec(dllexport) キーワードを使うと、データ、関数、クラス、クラスのメンバ関数を DLL からエクスポートできます。__declspec(dllexport) を使う場合、エクスポート用の .DEF ファイルは不要です。
関数をエクスポートするには、呼び出し規約キーワードが指定されている場合、__declspec(dllexport) キーワードは呼び出し規約キーワードの左に記述します。以下に例を示します。
__declspec(dllexport) void __cdecl Function1(void);
クラス内のすべてのパブリック データ メンバおよびメンバ関数をエクスポートするには、__declspec(dllexport) キーワードは、以下のようにクラス名の左に記述します。
class __declspec(dllexport) CExampleExport : public CObject
{ ... class definition ... };
DLL のビルド時には通常、エクスポートする関数のプロトタイプやクラスを含むヘッダー ファイルを作成し、そのヘッダー ファイル内の宣言に __declspec(dllexport) を追加します。コードを読みやすくするために、次のように __declspec(dllexport) 用のマクロを定義して、そのマクロをエクスポートする各シンボルに使います。
#define DllExport __declspec( dllexport )
__declspec(dllexport) は、関数名を DLL のエクスポート テーブルに格納します。テーブル サイズの最適化方法については、「名前ではなく序数による DLL 関数のエクスポート」を参照してください。
ただ単に__declspec(dllexport)を付けて
シンボルを定義しろ、と、そういうことです。
試しに関数をエクスポートしてみます。
まずAppWizardでスケルトンを作成。あとはひたすらコーディング。
[AppWizard]-[Win32 Dynamic-Link Library]- [単純なDLLプロジェクト]あたりで作成します。 プロジェクト名は"test"でやってみます。
// test.cpp : DLL アプリケーション用のエントリ ポイントを定義します。 // #include "stdafx.h" BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { return TRUE; }
作成されたのはソースファイル1個と
プリコンパイル済ヘッダー関連(StdAfx.h,StdAfx.cpp)です。
実行可能ファイルのスケルトンにはWinMain関数が追加されていますが、
代わりにDllMainという関数が追加されているだけです。
この関数はWinMainとかDOSのmain関数と同じような役割を果たすもので、
DLLがロードされれば最初にこの関数が呼ばれます。
ただし、WinMainなどとは違って、ここにだらだらと書くことはあまり無く、
グローバル変数の初期化とか、ちっちゃなこと(謎)を書きます。
パラメータについては良く分からんです。(ダメジャン
ようはここに関数を追加すればいいんですよ。
簡単な例ということで、二つの数の相加平均を求める関数を定義します。
(もうちょいましな関数書けや)
こんな感じでしょうか。
// test.cpp : DLL アプリケーション用のエントリ ポイントを定義します。 // #include "stdafx.h" #include "test.h" // さりげなくヘッダーをインクルード BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { return TRUE; } // 出た!ヘボ関数 int average(int n1,int n2) { return (n1+n2)/2; }
ただ関数を書けばいいんだって。
あとはインポート時のためのヘッダーを作るだけです。
DLLを利用してもらうときは、ビルドしてできたDLLファイルと
LIBファイル(インポートライブラリという)とヘッダーファイルの
三つが必要になります。
(インポートライブラリはなくても、どうにかなりますが…)
// test.h : TEST DLLのヘッダー #ifndef __TEST_H__ #define __TEST_H__ #ifdef TEST_EXPORTS #define _EXPORT __declspec(dllexport) #else #define _EXPORT __declspec(dllimport) #endif /* TEST_EXPORTS */ _EXPORT int average(int,int); #endif /* __TEST_H__ */
プリプロセッサばっか。なんだかなぁ。(笑
まず、複数回インクルードされる場合を防ぐ為に
__TEST_H__というキーワードを定義します。これは定番ですね。
次に_EXPORTというキーワードも定義します。
TEST_EXPORTSってのはAppWizardで作成されたスケルトンでは
必ず追加されています。
これは[プロジェクト]-[設定]-[C/C++]-[プリプロセッサの定義]を見れば
載っています。プロジェクト名に応じて変わってきますので臨機応変に。
ゆえに、[_EXPORTイコール__declspec(dllexport)]となります。
キーワードを定義して、間接的にエクスポートする(?)メリットは
TEST_EXPORTSの定義されていないプロジェクトで
このヘッダーがインクルードされたときに明らかになります。
そのとき、_EXPORTイコール__declspec(dllimport)となり、
関数はインポートされるからです。インポートについては
「エクスポートとインポートとリンク」
を見てください。
あとは_EXPORTを付けて関数を宣言すればいいわけです。
Jun. 29, 2002