如何:直接執行個體化 WRL 元件
學習如何使用 Windows 執行階段 C++ 樣板庫 (WRL) Microsoft::WRL::Make 和 Microsoft::WRL::Details::MakeAndInitialize 函式具現化從定義它的模組中的元件。
您可以直接具現化元件,您可以減少額外負荷,所以需要 Class Factory 或其他機制時。 您可以執行個體化元件直接在 Windows 市集 應用程式與傳統型應用程式。
若要了解如何使用 建立基本 Windows 執行階段 元件和具現化從外部 Windows 市集 應用程式,請參閱 逐步解說:使用 WRL 建立基本 Windows 執行階段元件。 若要了解如何使用 WRL 建立傳統 COM 元件和具現化從外部傳統型應用程式,請參閱 如何:使用 WRL 建立傳統 COM 元件。
這個文件顯示兩個範例。 第一個範例會使用 Make 函式產生元件。 第二個範例會使用 MakeAndInitialize 函式執行個體化可以在建構期間失敗的元件。 (由於 COM 一般會使用 HRESULT 值,而不是例外狀況,表示錯誤, COM 型別不是它的建構函式通常會擲回。 MakeAndInitialize 可讓元件透過 RuntimeClassInitialize 方法驗證其建構函式引數)。這個範例會定義基本記錄器介面並藉由定義類別實作該介面寫入訊息至主控台。
重要
您不能使用 new 運算子執行個體化 WRL 元件。因此,建議您一律使用 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. */
處理基本記錄器元件的建構失敗
使用下列程式碼取代 CConsoleWriter 類別的定義。 這個版本保留私用資料成員變數並覆寫 RuntimeClass::RuntimeClassInitialize 方法。 如果提供的參數是 nullptr,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_ 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的定義。 這個版本使用 MakeAndInitialize 產生兩個 CConsoleWriter 物件。 如需示範版本,請先呼叫成功和第二次呼叫失敗。
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