あえて C言語で COMコンポーネントを作る - 6 [前頁]   [次頁]   この記事の目次へ戻る   トップの目次に戻る

〜 6. 手順2 - DllMain 関数を作る 〜

  この頁では、サンプルの中の dllmain.c に含まれる DllMain 関数の作り方について確認します。
  DllMain 関数については、Visual C++ のプロジェクトを新規作成した時点の、既定のソースコードのままで問題ありません。 ただし、このサンプルでは、もともとあったヘッダーを消してしまったので、最小限のライブラリを参照するためにヘッダーを改めてインクルードする必要はあります。 ここでは、SmallLib.h というヘッダーを新たに作り、この中に Windows のライブラリを参照する上で最小限必要な記述をすることにします。
  ※ここでは、Visual C++ 2008 Express Edition SP1 を使用します。

・最小限のヘッダー ファイルを用意する
  とりあえず、以下の手順で、空のヘッダー ファイル SmallLib.h を作成してください。

(1) ソリューション エクスプローラのツリー上で、[SmallComp] プロジェクトノードを右クリックし、 ショートカットメニューが表示されたら、[追加][新しい項目] の順にクリックします。 (右クリックする場所は、ツリー上のルートノード(ソリューション)ではなく、その下のノード(プロジェクト)です。)
(2) [新しい項目の追加] ダイアログボックスが表示されたら、 左側の [カテゴリ] のツリーから、[Visual C++] ノードの配下にある [コードー] ノードを クリックして選択します。
(3) 引き続き、右側の [テンプレート] では、ヘッダー ファイル (.h) を選択します。
(4) 引き続き、以下の情報を入力します。
    ファイル名: SmallLib.h
    場所: C:\SmallCompSol\SmallComp
場所は、既定のパスのまま(プロジェクトがある場所)にします。みなさんが、ソリューションを配置した場所によって、このパスは異なります。
(5) 上記の設定が済んだら、[新しい項目の追加] ダイアログボックスの右下部にある [追加] をクリックします。

  このヘッダー ファイル SmallLib.h に次のコードを入力してください。
#pragma once
#define WIN32_LEAN_AND_MEAN /* Windows ヘッダーから使用されていない部分を除外する */
#include <windows.h>        /* Windows ヘッダー ファイル */

#include <objbase.h> /* COMで必要なヘッダーファイル */
  通常、COM コンポーネントを作る場合、最低限必要なインクールドすべきヘッダーは二つです。 一つは、Windows プログラミングを行う上で必要な windows.h です。 もう一つは、COM の基本的な定義を利用するために必要となる objbase.h です。
  使用する API によっては、これ以外にも必要なヘッダーはありますし、また、これとは違うヘッダーで置き換え可能の場合もあります。 しかし、ある程度汎用性があり、基本的なヘッダーのインクルードとしては、この例が妥当でしょう。
  なお、コメントにも書いてありますが、 WIN32_LEAN_AND_MEAN マクロを付けると、ヘッダーの参照する部分を基本機能に限定して少なくすることができます。

・DllMain 関数のため、必要なヘッダーをインクルードする
  すでに DllMain 関数のひな形はあるので、あとは前述のヘッダーをインクルードするだけです。
  既存の dllmain.c において、次のように SmallLib.h をインクルードするように修正してください。
// dllmain.cpp : DLL アプリケーションのエントリ ポイントを定義します。
#include "SmallLib.h"

BOOL APIENTRY DllMain( HMODULE 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;
}
  通常、DllMain 関数は、COM コンポーネントの利用開始や終了の時点で、必要に応じて何回か呼び出されます。
  DllMain 関数が呼び出された際には、ul_reason_for_call 引数には、その理由の値が格納されており、 今回のサンプルでは、クライアントから COM コンポーネントにアクセスを開始した際に、 ul_reason_for_call の値は DLL_PROCESS_ATTACH になって呼び出されます。また、COM コンポーネントのアクセス終了時には、 ul_reason_for_call の値は DLL_PROCESS_DETATCH になって呼び出されます。
  このタイミングを利用すれば、この DLL のライフタイムにおける初期処理や後処理も記述できます。

・(参考) 既存サンプルをデバッグする
  ここでの DllMain 関数の作成手順の説明は以上ですが、DllMain 関数の動きを知るためにも、既存サンプル SmallComp.sln のデバッグ方法を掲載しておきます。
  なお、ここでは、デバッグの基本的な操作方法は、ご存じであることを前提に、ポイントだけ説明します。

  今回の COM コンポーネントのような DLL では、起動すべきクライアントを指定する必要があります。 ここでは、クライアントとして Test.vbs を使用しているので、次のように設定します。

(1) ソリューション エクスプローラのツリー上で、[SmallComp] プロジェクトノードを右クリックし、[プロパティ] をクリックします。 (右クリックする場所は、ツリー上のルートノード(ソリューション)ではなく、その下のノード(プロジェクト)です。)
(2) [SmallComp プロパティ ページ] ダイアログボックスが表示されたら、 左側のツリーから、[構成プロパティ] ノードの配下にある [デバッグ] ノードをクリックして選択します。
(3) さらに右側のペインでは、次のように設定します。
  [コマンド] : C:\windows\system32\wscript.exe
  [コマンド引数] : $(SolutionDir)TestClient\Test.vbs
コマンドのパスは、OS が C: ドライブにインストールされていることを前提にしています。
また、$(SolutionDir) は予め定義されたマクロで、ソリューション フォルダを意味します。
(4) [OK] をクリックして、[SmallComp プロパティ ページ] ダイアログ ボックスを閉じます。

  これで準備完了です。あとは、普通にデバッグできます。
  C言語のソースコードの適当なところに、ブレークポイントを付けて、 [デバッグ] メニューの [デバッグ開始] をクリックすれば、通常どおりにデバッグできます。
  もちろん、COM コンポーネントをレジストリに予め登録しておく必要があるので、 まずは、サンプルの ReadMe.txt の手順に従って準備してください。

  なお、デバッグ起動時に「wscript.exe のデバッグ情報が見つからない ...」という警告が表示されますが、 たしかにその通りなので、そのまま [はい] をクリックして続行してください。
  また、Visual C++ 2008 Express Edition では、クライアントスクリプト自体のデバッグはサポートしていないそうです。

Copyright(C) Satoshi Yajima [前頁]   [次頁]   この記事の目次へ戻る   トップの目次に戻る