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. コードの作成
次のコードを 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() が呼び出されていることがわかります。