Практическое руководство. Непосредственное создание экземпляра компонентов WRL

Узнайте, как использовать библиотеку шаблонов среда выполнения Windows C++ (WRL)Microsoft::WRL::Make и Microsoft::WRL::D etails::MakeAndInitialize для создания экземпляра компонента из модуля, определяющего его.

С помощью создания компонентов напрямую можно уменьшить нагрузку, когда нет необходимости использовать фабрики классов или другие механизмы. Вы можете создать экземпляр компонента непосредственно в универсальная платформа Windows приложениях и в классических приложениях.

Чтобы узнать, как использовать библиотеку шаблонов C++ среда выполнения Windows для создания классического COM-компонента и создания экземпляра из внешнего классического приложения см. статью "Практическое руководство. Создание классического COM-компонента".

Здесь приведено два примера. В первом примере используется функция Make для создания экземпляра компонента. Во втором примере для создания компонента, который может создать ошибку во время построения, используется функция MakeAndInitialize. (Так как COM обычно использует значения HRESULT вместо исключений, чтобы указать ошибки, тип COM обычно не вызывается из конструктора. MakeAndInitialize позволяет компоненту проверить свои аргументы построения с помощью RuntimeClassInitialize метода.) Оба примера определяют базовый интерфейс средства ведения журнала и реализуют этот интерфейс, определяя класс, который записывает сообщения в консоль.

Важно!

Оператор нельзя использовать new для создания экземпляров среда выполнения Windows компонентов библиотеки шаблонов C++. Поэтому всегда рекомендуется использовать функцию Make или MakeAndInitialize, чтобы создать компонент напрямую.

Создание базового компонента средства ведения журнала и его экземпляров

  1. В Visual Studio создайте проект консольного приложения Win32. Назовите проект, например WRLLogger.

  2. Добавьте файл Midl File (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);
    }
    
  3. Чтобы заменить содержимое 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.
    */
    

Обработка сбоя построения для базового компонента средства ведения журнала

  1. Замените определение класса CConsoleWriter следующим кодом: Эта версия содержит частную строковую переменную-член и переопределяет метод RuntimeClass::RuntimeClassInitialize. RuntimeClassInitialize завершается ошибкой, если вызов завершается ошибкой SHStrDup .

    // 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);
        }
    };
    
  2. Замените 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.
    */
    

См. также

Библиотека шаблонов C++ для среды выполнения Windows (WRL)
Microsoft::WRL::Make
Microsoft::WRL::D etails::MakeAndInitialize