Attributed Programming による COM コンポーネントの作成方法

COM コンポーネントの Attributed Programming とは?

この資料では Attributed Programming による COM コンポーネントの作成方法を紹介します。Attributed Programming を用いると C/C++ を用いて簡単に COM コンポーネントが作成できるようになります。

Visual C++ コンパイラが COM コンポーネントの開発用に多数のサポートをしてくれます。

概要

Attributed Programming は COM コンポーネントの作成を容易にすることと .NET Framework 向けのコードを容易に作成できるよう、 Visual C++ に導入されました。この資料では COM コンポーネントの作成方法を紹介します。

この資料では、動くコードが出来上がるところを目標にしています。詳細については MSDN を参照してください。

それでは以下の手順で COM コンポーネントを作成しましょう。

  1. コードの作成
  2. ビルド
  3. テスト

1. コードの作成

次のコードを foo.cpp として保存してください。

#include "foo.h"
///////////////////////////////////////////////////////////////////////////////
//
// Module
//


[ module(dll, name = "SimpleCOM", helpstring = FOO_TYPELIB_HELP) ]
class CSimpleCOMModule { };


///////////////////////////////////////////////////////////////////////////////


STDMETHODIMP CFoo::Bar(void) {
     ::MessageBox (NULL, TEXT("Hello, COM!"), TEXT("Message"), MB_OK | MB_ICONINFORMATION);
     return S_OK;
}

続いてヘッダファイルです。foo.h として保存してください。

/*

COM Attributed Programming Skelton

September 5, 2003

*/

#pragma once

#define _ATL_APARTMENT_THREADED

#include <atlbase.h>
#include <atlcom.h>


///////////////////////////////////////////////////////////////////////////////
//
// Strings for attributes
//


#define FOO_PROGID "SimpleCOM.Foo.1"
#define FOO_PROGID_VI "SimpleCOM.Foo"
#define FOO_HELP_STRING "SimpleCOM class"
#define FOO_TYPELIB_HELP "SimpleCOM Type Library"


///////////////////////////////////////////////////////////////////////////////
//
// Interface
//


[ object, 
  dual,
  helpstring("IFoo Interface"), 
  pointer_default(unique)
]
__interface IFoo : IDispatch {

     [id(1), helpstring("Bar")] HRESULT Bar (void);

};


///////////////////////////////////////////////////////////////////////////////
//
// COM coclass
//


[ coclass, 
  threading("apartment"), 
  vi_progid(FOO_PROGID_VI), 
  progid(FOO_PROGID), 
  version(1.0), 
  helpstring(FOO_HELP_STRING)]
class ATL_NO_VTABLE CFoo : public IFoo {

public:
     // Constructor and Destructor
     CFoo() {}
     DECLARE_PROTECT_FINAL_CONSTRUCT()

     HRESULT FinalConstruct() {
          return S_OK;
     }
     
     void FinalRelease() {}

     // Methods
     STDMETHOD(Bar)(void);
};

makefile は次の通りです。

TARGETNAME=foo
OUTDIR=.\chk
LINK32=link.exe

ALL : "$(OUTDIR)\$(TARGETNAME).dll"

CPPFLAGS=\
	/nologo\
	/EHsc\
	/W3\
	/c\
	/ZI\
	/TP\
	/Fo"$(OUTDIR)\\"\
	/Fd"$(OUTDIR)\\"\
	/DWIN32\
	/D_ATL_ATTRIBUTES\
	/D_ATL_STATIC_REGISTRY\
	/DUNICODE\
	/D_UNICODE

LINK32_FLAGS=\
	kernel32.lib\
	ole32.lib\
	oleaut32.lib\
	uuid.lib\
	/OUT:$(OUTDIR)\$(TARGETNAME).dll\
	/DLL\
	/IDLOUT:"$(OUTDIR)\_$(TARGETNAME).idl"\
	/DEBUG\
	/PDB:"$(OUTDIR)\$(TARGETNAME).pdb"\
	/SUBSYSTEM:WINDOWS\
	/IMPLIB:"$(OUTDIR)\$(TARGETNAME).lib"\
	/MACHINE:X86
	
LINK32_OBJS=$(OUTDIR)\$(TARGETNAME).obj

"$(OUTDIR)\$(TARGETNAME).dll" : "$(OUTDIR)" $(LINK32_OBJS)
    $(LINK32) $(LINK32_FLAGS) $(LINK32_OBJS)

"$(OUTDIR)" :
    if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"

.c{$(OUTDIR)}.obj:
   $(CPP) $(CPPFLAGS) $<

.cpp{$(OUTDIR)}.obj:
   $(CPP) $(CPPFLAGS) $<

2. ビルド

上記のコードは既にビルド可能な形式になっていますので、さっそくビルドしてください。

> nmake

ビルドが成功し、サブディレクトリ chk の中に foo.dll が出来上がっていたら、次のコマンドで COM コンポーネントを登録します。

> regsvr32 .\chk\foo.dll

尚、以下のテストが終わったら以下のコマンドで COM の登録を解除できます。

> regsvr32 /u .\chk\foo.dll

3. テスト

テスト用のスクリプトは次の通りです。

Dim obj

Set obj = CreateObject("SimpleCOM.Foo")

obj.Bar()

Set obj = Nothing

> cscript test.vbs

これでポップアップメッセージが出てきたら成功です。 foo.cpp 内で実装した CFoo::Bar() が呼び出されていることがわかります。

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 Web/DB プログラミング徹底解説