Gewusst wie: Direktes Instanziieren von WRL-Komponenten

Erfahren Sie, wie Windows Runtime C++ Template Library (WRL) Microsoft::WRL::Make und Microsoft::WRL::Details::MakeAndInitialize-Funktionen verwendet, um eine Komponente aus dem Modul zu instanziieren, das sie definiert.

Wenn Sie Komponenten direkt instanziieren, können Sie Aufwand verringern, wenn Sie nicht Class Factory oder andere Mechanismen erfordern.Sie können eine Komponente direkt in beiden Windows Store-App und in den Desktop-Apps instanziieren.

Informationen zum Hinzufügen verwendet um eine grundlegende Windows-Runtime Komponente zu erstellen und sie von einer externen Windows Store-App zu instanziieren, finden Sie unter Exemplarische Vorgehensweise: Erstellen einer Basiskomponente für Windows-Runtime mit WRL.Informationen zum Hinzufügen WRL verwendet um eine klassische COM-Komponente zu erstellen und sie von einer externen Desktop-App zu instanziieren, finden Sie unter Gewusst wie: Erstellen einer klassischen COM-Komponente mit WRL.

Dieses Dokument enthält zwei Beispiele.Im ersten Beispiel wird die Make-Funktion, um eine Komponente zu instanziieren.Das zweite Beispiel verwendet die MakeAndInitialize-Funktion, um eine - Komponente zu instanziieren, die während der Konstruktion fehlschlagen kann.(Da COM normalerweise HRESULT-Werte, anstelle der Ausnahmen verwendet, um Fehler anzugeben, löst ein COM-Typ in der Regel nicht von ihrem Konstruktor aus.MakeAndInitialize aktiviert eine Komponente, um die Konstruktionsargumente durch die RuntimeClassInitialize-Methode zu überprüfen.) Beide Beispiele definieren eine grundlegende Protokollierungsschnittstelle und implementieren diese Schnittstelle, indem eine Klasse definieren, die Nachrichten an die Konsole ausgibt.

Wichtiger HinweisWichtig

Sie können den new-Operator nicht verwenden, um WRL Komponenten zu instanziieren.Daher wird empfohlen, immer Make oder MakeAndInitialize verwenden, um eine Komponente direkt zu instanziieren.

So fügen Sie eine einfache Protokollierungskomponente erstellen und instanziieren

  1. In Visual Studio erstellen Sie ein Projekt Win32-Konsolenanwendung.Nennen Sie das Projekt beispielsweise WRLLogger.

  2. Fügen Midl-Datei (.idl) eine Datei zum Projekt hinzu, benennen Sie die Datei ILogger.idl und anschließend diesen Code hinzu:

    import "ocidl.idl";
    
    // Prints text to the console.
    [uuid(AFDB9683-F18A-4B85-90D1-B6158DAFA46C)]
    interface ILogger : IUnknown
    {
        HRESULT Log([in] BSTR text);
    }
    
  3. Verwenden Sie folgenden Code, um den Inhalt von WRLLogger.cpp zu ersetzen.

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

So Konstruktionsfehler für die grundlegende Protokollierungskomponente behandeln

  1. Verwenden Sie den folgenden Code, um die Definition der CConsoleWriter-Klasse zu ersetzen.Diese Version enthält eine private Zeichenfolgenmembervariable an und überschreibt die - Methode RuntimeClass::RuntimeClassInitialize.RuntimeClassInitialize schlägt fehl, wenn der bereitgestellte Parameter nullptr ist.

    // 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. Verwenden Sie den folgenden Code, um die Definition von _tmain zu ersetzen.Diese Version MakeAndInitialize verwendet, um zwei CConsoleWriter-Objekte zu instanziieren.Für Demonstration folgt der erste Aufruf und der zweite Aufruf schlägt fehl.

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

Siehe auch

Referenz

Microsoft::WRL::Make

Microsoft::WRL::Details::MakeAndInitialize

Konzepte

Windows Runtime C++ Template Library (WRL)