Cómo: Crear instancias de componentes WRL directamente

Obtenga información sobre cómo usar las funciones de la biblioteca de plantillas Windows Runtime C++ (WRL) Microsoft::WRL::Make y Microsoft::WRL::Details::MakeAndInitialize para crear instancias de un componente a partir del módulo que lo define.

La creación de instancias de componentes directamente permite reducir la sobrecarga cuando no se necesitan generadores de clases u otros mecanismos. Se pueden crear instancias de un componente directamente en las aplicaciones de la Plataforma universal de Windows y en las aplicaciones de escritorio.

Para obtener información sobre cómo usar la biblioteca de plantillas Windows Runtime C++ para crear un componente COM clásico y crear una instancia de él desde una aplicación de escritorio externa, consulte Como crear un componente COM clásico.

En este documento se muestran dos ejemplos. El primer ejemplo utiliza la función Make para crear una instancia de un componente. El segundo ejemplo utiliza la función MakeAndInitialize para crear una instancia de un componente que pueden producir errores durante la construcción. (Dado que COM normalmente usa los valores HRESULT, en lugar de excepciones, para indicar errores, un tipo COM normalmente no inicia desde su constructor. MakeAndInitialize permite que un componente valide sus argumentos de construcción a través del método RuntimeClassInitialize). Ambos ejemplos definen una interfaz básica del registrador e implementan esa interfaz definiendo una clase que escribe mensajes en la consola.

Importante

No puedes usar el new operador para crear instancias de los componentes de la biblioteca de plantillas de C++ de Windows Runtime. Por tanto, se recomienda usar siempre Make o MakeAndInitialize para crear instancias de un componente directamente.

Para crear un componente básico de registrador y crear instancias del mismo

  1. En Visual Studio, cree un proyecto de Aplicación de consola Win32. Asigne un nombre al proyecto, por ejemplo, WRLLogger.

  2. Agregue un archivo Midl File (.idl) al proyecto, nombre el archivo ILogger.idl y después agregue 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. Utilice el código siguiente para reemplazar el contenido 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 controlar el error de construcción del componente básico de registrador

  1. Utilice el código siguiente para reemplazar la definición de la clase CConsoleWriter. Esta versión contiene una variable miembro privada de cadena y reemplaza el método RuntimeClass::RuntimeClassInitialize. RuntimeClassInitialize produce un error si la llamada a SHStrDup es fallida.

    // 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. Utilice el código siguiente para reemplazar la definición de wmain. Esta versión usa MakeAndInitialize para crear una instancia del objeto CConsoleWriter y comprueba el resultado de 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.
    */
    

Consulte también

Biblioteca de plantillas C++ de Windows en tiempo de ejecución (WRL)
Microsoft::WRL::Make
Microsoft::WRL::Details::MakeAndInitialize