方法: WRL コンポーネントを直接インスタンス化する
Windows ランタイム C++ テンプレート ライブラリ (WRL) の Microsoft::WRL::Make と Microsoft::WRL::Details::MakeAndInitialize の関数を使用して、コンポーネントを定義するモジュールからそのコンポーネントをインスタンス化する方法について説明します。
コンポーネントを直接インスタンス化することにより、クラス ファクトリやその他の機構が必要ない場合にオーバーヘッドを低減できます。 ユニバーサル Windows プラットフォーム アプリとデスクトップ アプリの両方で、コンポーネントを直接インスタンス化することができます。
Windows ランタイム C++ テンプレート ライブラリを使ってクラシック COM コンポーネントを作成し、外部のデスクトップ アプリからインスタンス化する方法については、クラシック COM コンポーネントを作成する方法に関するページを参照してください。
このドキュメントでは、2 つの例を示します。 最初の例では、Make
関数を使用してコンポーネントをインスタンス化します。 2 番目の例では、MakeAndInitialize
関数を使用して構築中に失敗する場合があるコンポーネントをインスタンス化します (COM は通常、エラーを示すために例外ではなく HRESULT 値を使用するため、通常、COM 型はコンストラクターからスローしません。 MakeAndInitialize
を使用すると、コンポーネントは RuntimeClassInitialize
メソッドを使用してその構築引数を検証できます。どちらの例も、基本的なロガー インターフェイスを定義し、コンソールにメッセージを書き込むクラスを定義することによって、そのインターフェイスを実装します。
重要
new
演算子を使用して C++ テンプレート ライブラリ コンポーネントWindows ランタイムインスタンス化することはできません。 そのため、コンポーネントを直接インスタンス化するには、常に Make
または MakeAndInitialize
を使用することをお勧めします。
基本的なロガー コンポーネントを作成してインスタンス化するには
Visual Studio で、[Win32 コンソール アプリケーション] プロジェクトを作成します。 プロジェクトに WRLLogger などの名前を付けます。
プロジェクトに Midl ファイル (.idl) を追加してファイルに
ILogger.idl
という名前を付け、次のコードを追加します。import "ocidl.idl"; // Prints text to the console. [uuid(AFDB9683-F18A-4B85-90D1-B6158DAFA46C)] interface ILogger : IUnknown { HRESULT Log([in] LPCWSTR text); }
次のコードを使用して
WRLLogger.cpp
の内容を置き換えます。#include "pch.h" // Use stdafx.h in Visual Studio 2017 and earlier #include <wrl\implements.h> #include <comutil.h> #include "ILogger_h.h" using namespace Microsoft::WRL; // Writes logging messages to the console. class CConsoleWriter : public RuntimeClass<RuntimeClassFlags<ClassicCom>, ILogger> { public: STDMETHODIMP Log(_In_ PCWSTR text) { wprintf_s(L"%s\n", text); return S_OK; } private: // Make destroyable only through Release. ~CConsoleWriter() { } }; int wmain() { ComPtr<CConsoleWriter> writer = Make<CConsoleWriter>(); HRESULT hr = writer->Log(L"Logger ready."); return hr; } /* Output: Logger ready. */
基本的なロガー コンポーネントの構造エラーを処理するには
次のコードを使用して
CConsoleWriter
クラスの定義を置き換えます。 このバージョンは、プライベート文字列のメンバー変数を保持し、RuntimeClass::RuntimeClassInitialize
メソッドをオーバーライドします。SHStrDup
の呼び出しに失敗した場合、RuntimeClassInitialize
は失敗します。// Writes logging messages to the console. class CConsoleWriter : public RuntimeClass<RuntimeClassFlags<ClassicCom>, ILogger> { public: // Initializes the CConsoleWriter object. // Failure here causes your object to fail construction with the HRESULT you choose. HRESULT RuntimeClassInitialize(_In_ PCWSTR category) { return SHStrDup(category, &m_category); } STDMETHODIMP Log(_In_ PCWSTR text) { wprintf_s(L"%s: %s\n", m_category, text); return S_OK; } private: PWSTR m_category; // Make destroyable only through Release. ~CConsoleWriter() { CoTaskMemFree(m_category); } };
次のコードを使用して
wmain
の定義を置き換えます。 このバージョンは、MakeAndInitialize
を使用してCConsoleWriter
オブジェクトのインスタンスを作成し、HRESULT の結果を確認します。int wmain() { ComPtr<CConsoleWriter> writer; HRESULT hr = MakeAndInitialize<CConsoleWriter>(&writer, L"INFO"); if (FAILED(hr)) { wprintf_s(L"Object creation failed. Result = 0x%x", hr); return hr; } hr = writer->Log(L"Logger ready."); return hr; } /* Output: INFO: Logger ready. */
関連項目
Windows ランタイム C++ テンプレート ライブラリ (WRL)
Microsoft::WRL::Make
Microsoft::WRL::Details::MakeAndInitialize