如何:直接实例化 WRL 组件

了解如何使用 Windows 运行时 C++ 模板库 (WRL) Microsoft::WRL::MakeMicrosoft::WRL::Details::MakeAndInitialize 函数实例化定义它的模块的元素。

通过直接实例化组件,可以降低开销,当您不需要选件类工厂或其他框架时。可以实例化一个元素直接在两 Windows 应用商店 apps 和在桌面 apps。

若要了解如何使用 创建一个基本的 Windows 运行时 元素并将其实例化从外部 Windows 应用商店 app,请参见 演练:使用 WRL 创建基本 Windows 运行时组件。若要了解如何使用 WRL 创建一个传统的 COM 组件和实例化它从外部桌面 app,请参见 如何:使用 WRL 创建传统型 COM 组件

本文档演示两个示例。第一个示例使用 Make 函数实例化组件。第二个示例使用 MakeAndInitialize 函数实例化可以在构造时失败的元素。(由于 COM 通常使用 HRESULT 值,而不是异常,指示错误,COM 类型不从其构造函数通常引发。MakeAndInitialize 使组件通过 RuntimeClassInitialize 方法以验证其构造实参。)两个示例定义一个基本的记录器接口并通过定义选件类实现该接口该消息写入个控件。

重要说明重要事项

不能使用 new 运算符实例化 WRL 元素。因此,建议您始终使用 MakeMakeAndInitialize 直接实例化组件。

创建和实例化一个基本的记录器元素

  1. 在 Visual Studio 中,创建一个 Win32 控制台应用程序 项目。将项目命名为,例如,WRLLogger。

  2. 添加一 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);
    }
    
  3. 使用以下代码替换 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.
    */
    

处理基本的记录器组件的构造失败

  1. 使用以下代码替换 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()
        {
        }
    };
    
  2. 使用以下代码替换 _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::Make

Microsoft::WRL::Details::MakeAndInitialize

概念

Windows 运行时 C++ 模板库 (WRL)