Tips of VC++ >
DLL >
暗黙的リンク
★ 前へ戻る ★ 次へ進む ★
このドキュメントにはサンプルプログラムが含まれています。
ワークスペース
ソースファイル(テキスト)
最初に「DLL概要」と 「エクスポートとインポートとリンク」を 読むと、すんなりと理解できるでしょう。 はっきりした理由がない限り、リンク方法には暗黙的リンクをお薦めします。 ただし、この方法を使うときは以下のファイルが必要になってきます。
これだけのファイルが揃っていれば、あとは手順どおりです。 ヘッダーをインクルード、インポートライブラリとリンク、関数呼び出し。 ハイ、終了〜。簡単ですね。MSDNでも同じことが書いてあります。
DLL を使う実行形式は、各ソース ファイル内のエクスポート関数 (または C++ クラス) を含むヘッダー ファイルをインクルードする必要があります。各ソース ファイルには、エクスポート関数の呼び出しが含まれています。コーディングの面から見ると、エクスポート関数の関数呼び出しは、その他の関数呼び出しとほとんど同じです。
実行可能ファイルの呼び出しをビルドするには、インポート ライブラリとリンクする必要があります。外部メイクファイルを使う場合は、リンクするその他のオブジェクト ファイル (.OBJ) やライブラリを列記したインポート ライブラリのファイル名を指定します。Visual C++ の開発環境で作業する場合は、[プロジェクトの設定] ダイアログ ボックスの [リンク] タブの [オブジェクト/ライブラリ モジュール] ボックスに、インポート ライブラリ名を指定します。
このへんで蛇足を一つ。別に飛ばしてもけっこうです。(主にMSDNの翻訳)
まずDLLを使用するアプリケーションをビルドしたときに何が起こるのでしょう? DLL関数を呼び出す実行形式のソースコードをコンパイルすると、 オブジェクトコード内に外部関数への参照が生成されます。 このとき、関数の定義はもちろん存在しないので、そのままコンパイルすると 外部参照が未解決でなんちゃらかんちゃらと言う お馴染みの(笑)エラーが出るはずです。 そこでアプリケーションをインポートライブラリファイルと リンクする必要が生じるのです。
インポートライブラリには、DLLをロードし、DLL内の関数呼び出しを インプリメントするコードが含まれているだけです。 リンカは、インポートライブラリ内に外部関数を見つけると、 その関数のコードはDLL内にあるものと認識します。 リンカは、単にDLLコードの場所を実行可能ファイルに記入することによって、 外部参照を解決します。システムはプロセスの起動時にこの情報を利用します。
プログラムが起動されるとまず、DLLをロードし、 モジュールがプロセスのアドレス空間にマップされます。 そして、エントリポイント関数(初期化および終了コード用)を呼び出します。 これがDllMain関数ですね。 このときのパラメータの1つは、DLLがプロセスにアタッチされようと していることを示すコードになります。
その後、システムはプロセスの実行可能コードを変更し、 そのDLL関数の開始アドレスをセットします。 これでDLL関数はアプリケーション自身の関数と同じように扱われるのです。
サンプルを作ってみます。 「__declspec(dllexport)を使ってエクスポート」 で作ったDLLを使用します。
作業フォルダに適当なフォルダを作り、 ヘッダーとインポートライブラリをコピーします。 DLL本体はdebugフォルダとかreleaseフォルダにいれてください。 実行ファイルと同じディレクトリに入れないとエラーが出ます。
まず、ヘッダーをインクルードします。 "stdafx.h"に追加するのが一般的ですね。
次にインポートライブラリをリンクするようにします。 [プロジェクト]-[設定]-[リンク]-[オブジェクト/ライブラリ モジュール]に パスを追加してください。
これで下準備は完了です。 あとはひたすら関数を使う。使う!使う!! サンプルのDLLに含まれていた関数はaverageでしたね。 こんな感じでしょうか。
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { int n= average(32,56); char buf[10]; ::wsprintf(buf,"%d",n); ::MessageBox(NULL,buf,"DLLのてすと",MB_OK); return 0; }
無駄にダイアログを表示させてみました。 44と表示されるはずです。
Jul. 2, 2002