チュートリアル : テキスト エディタを使った COM サーバーの作成

属性は、面倒で複雑な従来の COM プログラミングを簡単にするために開発されました。属性を使ってアプリケーションを開発することで、COM の一般的な手順の多くを自動化したり簡略化したりできます。このチュートリアルでは、テキスト エディタとコマンド ライン ツールを使って、簡単な COM サーバーを開発します。

アプリケーションで属性を使用するには、関連するマクロ (_ATL_ATTRIBUTES など) を定義し、関連するヘッダー ファイルをインクルードして、属性のサポートを追加する必要があります。

ヘッダー ファイルを作成するには

  1. メモ帳または任意のテキスト エディタを開きます。

  2. MyIncludes.h という名前の新しいファイルを作成します。

  3. 次のコードを追加します。

    #pragma once
    #define STRICT
    #ifndef _WIN32_WINNT
    #define _WIN32_WINNT 0x0400
    #endif
    #define _ATL_ATTRIBUTES
    #define _ATL_APARTMENT_THREADED
    #define _ATL_NO_AUTOMATIC_NAMESPACE
    #include <atlbase.h>
    #include <atlcom.h>
    #include <atlwin.h>
    #include <atltypes.h>
    #include <atlctl.h>
    #include <atlhost.h>
    using namespace ATL;
    
  4. ファイルを保存します。

"atl" で始まるインクルード ファイルは、アプリケーションに ATL のサポートを加えます。_ATL_ATTRIBUTES の定義により、属性付き ATL プログラミングのサポートも追加されます。

インプロセス サーバーを実装するソース ファイルを作成する必要があります。

ソース ファイルを作成するには

  1. メモ帳で、MyServer.cpp という名前の新しいファイルを作成します。

  2. 次のコードを追加します。

    #include "MyIncludes.h"
    // The module attribute is specified in order to implement DllMain,
    // DllRegisterServer and DllUnregisterServer
    [ module(dll, name = "MyServer", helpstring = "MyServer 1.0 Type Library") ];
    [ emitidl ];
    
  3. ファイルを保存します。

module 属性を使うと、COM インプロセス サーバーに必要な機能を実装する手間が省かれます。また、.idl ファイルまたは .def ファイル (サーバーの関数をエクスポートするファイル) を記述する必要もありません。これらの作業はすべて、module 属性によって自動的に行われます。

プロジェクトをビルドするには

  • コマンド ラインに次のコマンドを入力します。

    cl /LD MyServer.cpp
    regsvr32 MyServer.dll
    

エラーが発生した場合は、Visual Studio が正しくインストールされ、環境変数が定義されていることを確認してください。Visual Studio 環境変数は、[Visual Studio 2005 コマンド プロンプト] を実行して自動的に定義することも、<Visual Studio インストール ディレクトリ>\Common7\Tools\vsvars32.bat にある vsvars32.bat を実行して手動で設定することもできます。

プロジェクトが正常にビルドされると、オペレーティング システムにサーバーが登録されます。

この時点では、COM サーバーはクライアントに対してどの機能も公開していません。これは、COM サーバーにサーバー オブジェクトが実装されていないためです。次の手順として、このサーバーにサーバー オブジェクトを追加します。

サーバーにサーバー オブジェクトを追加するには

  1. MyServer.cpp を開き、次のコードを追加します。

    /////////////////////////////////////////////////////////////////////////////
    // IObject1
    [
       object,
       uuid("103FF9D9-8BC9-4ea8-8CD4-C1E627D04358"),
       dual,
       helpstring("IObject1 Interface"),
       pointer_default(unique)
    ]
    __interface IObject1 : IDispatch
    {
       HRESULT GetANum([out, retval]int* pInt);
    };
    /////////////////////////////////////////////////////////////////////////////
    // CObject1
    [
       coclass,
       threading(apartment),
       vi_progid("MyServer.Object1"),
       progid("MyServer.Object1.1"),
       version(1.0),
       uuid("15615078-523C-43A0-BE6F-651E78A89213"),
       helpstring("Object1 Class")
    ]
    class ATL_NO_VTABLE CObject1 : 
       public IObject1
    {
    public:
       CObject1()
       {
       }
       HRESULT GetANum(int* pInt){
          *pInt = 101;
          return S_OK;
       }
       DECLARE_PROTECT_FINAL_CONSTRUCT()
       HRESULT FinalConstruct()
       {
          return S_OK;
       }
    
       void FinalRelease() 
       {
       }
    };
    
  2. 変更を保存し、新しいコードをチェックします。

このコードにより、メソッドを 1 つ持つカスタム インターフェイス (IObject1) を実装する、簡単な COM オブジェクト (CObject1) が作成されます。このメソッド (GetANum) は、データ メンバの値 (int 型) を返します。

変更を保存し、前の手順と同じコマンドを使って、アプリケーションを再ビルドします。

cl /LD MyServer.cpp
regsvr32 MyServer.dll

サーバーが動作するかどうかを調べるには、テスト用のクライアント アプリケーションを作成する必要があります。

テスト用クライアント アプリケーションを作成するには

  1. メモ帳を開き、Comtest.cpp という名前の新しいファイルを作成します。

    Comtest.cpp は、MyServer.cpp と同じフォルダにある必要があります。

  2. Comtest.cpp に次のコードを追加します。

    #include <iostream>
    #include "atlbase.h"
    #import "vc90.tlb" no_namespace
    using namespace std;
    int main()
    {
       CoInitialize(NULL);
       {
          CComPtr<IUnknown> spUnknown;
                spUnknown.CoCreateInstance(__uuidof(CObject1));
          CComPtr<IObject1> pI;
          spUnknown.QueryInterface(&pI);
          int res = 0;
          res = pI->GetANum();
          cout << res << endl;
       }
       CoUninitialize();
    }
    

クライアント側でサーバーの正しい動作を認識するには、#import キーワードを使って、サーバーのタイプ ライブラリをインポートする必要があります。サーバーを作成するときに名前を指定していないため、コンパイラによって生成されたタイプ ライブラリは、既定の名前 (vc90.tlb) になっています。前掲のコードの中にある次の行で、ライブラリがインポートされます。

#import "vc90.tlb" no_namespace

このファイルがテスト用アプリケーションにインポートされると、クライアントは COM サーバーの型情報にアクセスできます。型情報にアクセスできると、テスト用アプリケーションは、その中で定義されている任意の型 (CObject1 や IObject1 など) を参照できます。

テスト アプリケーションをビルドおよび実行するには

  1. コマンド ラインに次のコマンドを入力します。

    cl /EHsc comtest.cpp
    
  2. 次のコマンドを入力して、アプリケーションを実行します。

    comtest
    

整数値が出力されます。

参照

概念

COM 属性による COM DLL の開発

チュートリアル : ウィザードを使った COM サーバーの作成