方法: WRL コンポーネントを直接インスタンス化する
Windows ランタイム C++ テンプレート ライブラリ (WRL) Microsoft::WRL::Make と Microsoft::WRL::Details::MakeAndInitialize 関数の要素を定義したモジュールからコンポーネントをインスタンス化する方法について説明します。
コンポーネントを直接インスタンス化することにより、クラス ファクトリまたはそのほかの機構が必要ない場合は、オーバーヘッドを低減できます。Windows ストア の両方の apps とデスクトップ アプリケーション コンポーネントを直接インスタンス化できます。
詳細については を Windows ランタイム の基本的なコンポーネントを作成および Windows ストア 外部アプリケーションからのインスタンスを作成する方法を チュートリアル: WRL を使用した基本的な Windows ランタイム コンポーネントの作成"を参照してください。詳細については WRL を従来の COM コンポーネントを作成および外部デスクトップ アプリケーションからインスタンスを作成する方法を 方法: WRL を使用して従来の COM コンポーネントを作成するを参照してください。
このドキュメントでは、2 例を次に示します。最初の例では、コンポーネントをインスタンス化するために Make 関数を使用します。2 番目の例は、構築時に失敗したことがあるコンポーネントをインスタンス化するために MakeAndInitialize 関数を使用します。エラーを示すために、COM が例外ではなく、通常 HRESULT の値が使用されるため、COM (通常はコンストラクターからスロー入力します。MakeAndInitialize は RuntimeClassInitialize のメソッドによって構築引数を検証することにより、コンポーネントを)どちらの例も、基本的なロガーのインターフェイスを定義し、メッセージをコンソールにクラスを定義して、そのインターフェイスを実装します。
![]() |
---|
WRL のコンポーネントをインスタンス化するために new の演算子は使用できません。したがって、は、コンポーネントを直接インスタンス化に 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] BSTR text); }
WRLLogger.cpp の内容を置き換えるには、次のコードを使用します。
#include "stdafx.h" #include <wrl\implements.h> #include <comutil.h> #include "ILogger_h.h" // comutil.h requires static linkage to comsuppw.lib. #pragma comment(lib, "comsuppw") using namespace Microsoft::WRL; // Writes logging messages to the console. class CConsoleWriter : public RuntimeClass<RuntimeClassFlags<ClassicCom>, ILogger> { public: STDMETHODIMP Log(_In_ BSTR text) { if (text == nullptr) { return E_POINTER; } wprintf_s(L"%s\n", text); return S_OK; } private: // Make destroyable only through Release. ~CConsoleWriter() { } }; int _tmain() { ComPtr<CConsoleWriter> writer = Make<CConsoleWriter>(); HRESULT hr = writer->Log(L"Logger ready."); return hr; } /* Output: Logger ready. */
基本的な logger コンポーネントの構造体のエラーを処理するには
CConsoleWriter クラスの定義を置き換えるには、次のコードを使用します。このバージョンは、プライベート文字列のメンバー変数を保持し、RuntimeClass::RuntimeClassInitialize のメソッドをオーバーライドします。RuntimeClassInitialize は、指定されたパラメーターが nullptrである場合に失敗します。
// 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_ BSTR category) { if (category == nullptr) { return E_POINTER; } m_category = category; return S_OK; } STDMETHODIMP Log(_In_ BSTR text) { if (text == nullptr) { return E_POINTER; } wprintf_s(L"%s: %s\n", m_category.GetBSTR(), text); return S_OK; } private: _bstr_t m_category; // Make destroyable only through Release. ~CConsoleWriter() { } };
_tmainの定義を置き換えるには、次のコードを使用します。このバージョンは CConsoleWriter の 2 種類のオブジェクトをインスタンス化するために MakeAndInitialize を使用します。デモについては、最初の呼び出しは成功し、目は失敗します。
int _tmain() { BSTR category = L"INFO"; ComPtr<CConsoleWriter> writer; HRESULT hr = MakeAndInitialize<CConsoleWriter>(&writer, category); if (FAILED(hr)) { wprintf_s(L"Object creation failed. Result = 0x%x", hr); return hr; } hr = writer->Log(L"Logger ready."); if (FAILED(hr)) { return hr; } wprintf_s(L"\n"); category = nullptr; hr = MakeAndInitialize<CConsoleWriter>(&writer, category); if (FAILED(hr)) { wprintf_s(L"Object creation failed. Result = 0x%x.\n", hr); return hr; } else { return writer->Log(L"Logger ready."); } } /* Output: INFO: Logger ready. Object creation failed. Result = 0x80004003. */
参照
関連項目
Microsoft::WRL::Details::MakeAndInitialize