Como instanciar componentes WRL diretamente

Saiba como usar as funções Microsoft::WRL::Make e Microsoft::WRL::D etails::MakeAndInitialize da WRL (Biblioteca de Modelos C++ do Windows Runtime) para instanciar um componente do módulo que o define.

Ao instanciar componentes diretamente, você poderá reduzir a sobrecarga quando não precisar de fábricas de classes ou outros mecanismos. Você pode criar uma instância de um componente diretamente em aplicativos da Plataforma Universal do Windows e em aplicativos da área de trabalho.

Para saber como usar a Biblioteca de Modelos C++ do Windows Runtime para criar um componente COM clássico e instanciá-lo em um aplicativo de área de trabalho externo, confira Como criar um componente COM clássico.

Este documento mostra dois exemplos. O primeiro exemplo usa a função Make para instanciar um componente. O segundo exemplo usa a função MakeAndInitialize para instanciar um componente que pode falhar durante a construção. (Como o COM normalmente usa valores HRESULT em vez de exceções para indicar erros, um tipo COM normalmente não gera exceções do próprio construtor. MakeAndInitialize permite que um componente valide os argumentos de construção dele por meio do método RuntimeClassInitialize.) Ambos os exemplos definem uma interface básica de agente e implementam essa interface definindo uma classe que grava mensagens no console.

Importante

Você não pode usar o new operador para instanciar componentes da Biblioteca de Modelos C++ do Tempo de Execução do Windows. Portanto, recomendamos que você sempre use Make ou MakeAndInitialize instancie um componente diretamente.

Para criar e instanciar um componente básico do agente

  1. No Visual Studio, crie um projeto de aplicativo de console Win32. Nomeie o projeto, por exemplo, WRLLogger.

  2. Adicione um arquivo Midl File (.idl) ao projeto, nomeie o arquivo ILogger.idl e adicione este código:

    import "ocidl.idl";
    
    // Prints text to the console.
    [uuid(AFDB9683-F18A-4B85-90D1-B6158DAFA46C)]
    interface ILogger : IUnknown
    {
        HRESULT Log([in] LPCWSTR text);
    }
    
  3. Use o código a seguir para substituir o conteúdo de 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.
    */
    

Para lidar com a falha de construção para o componente do agente básico

  1. Use o código a seguir para substituir a definição da classe CConsoleWriter. Esta versão contém uma variável de membro de cadeia de caracteres privada e substitui o método RuntimeClass::RuntimeClassInitialize. RuntimeClassInitialize falhará se a chamada para SHStrDup falhar.

    // 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. Use o código a seguir para substituir a definição de wmain. Esta versão usa MakeAndInitialize para instanciar o objeto CConsoleWriter e verificar o resultado 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.
    */
    

Confira também

WRL (Biblioteca de Modelos C++ do Tempo de Execução do Windows)
Microsoft::WRL::Make
Microsoft::WRL::Details::MakeAndInitialize