Comment : instancier directement les composants WRL

Apprenez comment utiliser Bibliothèque de modèles Windows Runtime C++ (WRL) Microsoft::WRL::Make et des fonctions d' Microsoft::WRL::Details::MakeAndInitialize pour instancier un composant du package qui le définit.

En instanciant des composants directement, vous pouvez réduire la charge mémoire lorsque vous n'avez pas besoin de fabriques de classe ou d'autres mécanismes.Vous pouvez instancier un composant directement dans les deux applications d' Windows Store et dans les applications de bureau.

Pour savoir comment utiliser pour créer un composant de base d' Windows Runtime et l'instanciation d'une application externe d' Windows Store, consultez Procédure pas à pas : création d'un composant Windows Runtime de base à l'aide de WRL.Pour savoir comment utiliser WRL pour créer un composant COM classique et l'instanciation d'une application de bureau externe, consultez Comment : créer un composant COM classique à l'aide de WRL.

Ce document montre deux exemples.Le premier exemple utilise la fonction d' Make pour instancier un composant.Le deuxième exemple utilise la fonction d' MakeAndInitialize pour instancier un composant qui peut échouer pendant la construction.(Comme COM utilise généralement des valeurs d' HRESULT, au lieu des exceptions, pour indiquer des erreurs, un type COM en général ne lève pas de constructeur.MakeAndInitialize permet à un composant de valider ses arguments de construction via la méthode d' RuntimeClassInitialize .) Les deux exemples définissent une interface de base du journal et implémente cette interface en définissant une classe qui écrit des messages dans la console.

Important

Vous ne pouvez pas utiliser l'opérateur d' new pour instancier des composants d' WRL .Par conséquent, nous vous recommandons toujours Make ou MakeAndInitialize pour instancier un composant directement.

Pour créer et instancier un composant de base du journal

  1. Dans Visual Studio, créez un projet de Application console Win32 .Nommez le projet, par exemple, WRLLogger.

  2. Ajoutez un fichier Fichier Midl (.idl) au projet, nommez le fichier ILogger.idl, puis ajoutez le code suivant :

    import "ocidl.idl";
    
    // Prints text to the console.
    [uuid(AFDB9683-F18A-4B85-90D1-B6158DAFA46C)]
    interface ILogger : IUnknown
    {
        HRESULT Log([in] BSTR text);
    }
    
  3. Utilisez le code suivant pour remplacer le contenu de 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.
    */
    

Pour gérer l'échec de construction pour le composant de base du journal

  1. Utilisez le code suivant pour remplacer la définition de la classe d' CConsoleWriter .Cette version contient une variable membre privée de chaîne et substitue la méthode d' RuntimeClass::RuntimeClassInitialize .RuntimeClassInitialize échoue si le paramètre fourni est nullptr.

    // 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. Utilisez le code suivant pour remplacer la définition d' _tmain.Cette version utilise MakeAndInitialize pour instancier deux objets d' CConsoleWriter .Pour une démonstration, le premier appel réussit et le deuxième appel échoue.

    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.
    */
    

Voir aussi

Référence

Microsoft::WRL::Make

Microsoft::WRL::Details::MakeAndInitialize

Concepts

Bibliothèque de modèles Windows Runtime C++ (WRL)