Freigeben über


Gewusst wie: Direktes Instanziieren von WRL-Komponenten

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

Durch die direkte Instanziierung von Komponenten können Sie den Mehraufwand reduzieren, wenn Klassenfactorys oder andere Mechanismen nicht benötigt werden. Sie können eine Komponente sowohl in Windows Store-Apps als auch in Desktop-Apps direkt instanziieren.

Wie Sie mit WRL eine grundlegende Windows-Runtime-Komponente erstellen und sie aus einer externen Windows Store-App instanziieren, erfahren Sie unter Exemplarische Vorgehensweise: Erstellen einer Basiskomponente für Windows-Runtime mit WRL. Wie Sie mit WRL eine klassische COM-Komponente erstellen und sie aus einer externen Desktop-App instanziieren, erfahren Sie unter Gewusst wie: Erstellen einer klassischen COM-Komponente mit WRL.

Dieses Dokument enthält zwei Beispiele. Im ersten Beispiel wird eine Komponente mit der Make-Funktion instanziiert. Im zweiten Beispiel wird eine Komponente mit der MakeAndInitialize-Funktion instanziiert, die bei der Erstellung einen Fehler verursachen kann. (Da COM Fehler normalerweise mit HRESULT-Werten anstelle von Ausnahmen anzeigt, wird ein COM-Typ normalerweise nicht von seinem Konstruktor ausgelöst. MakeAndInitialize aktiviert eine Komponente, um ihre Konstruktionsargumente durch die RuntimeClassInitialize-Methode zu aktivieren.) Beide Beispiele definieren eine grundlegende Protokollierungsschnittstelle und implementieren diese Schnittstelle durch Definition einer Klasse, die Nachrichten an die Konsole ausgibt.

Wichtig

Mit dem Operator new können WRL-Komponenten nicht instanziiert werden.Daher wird empfohlen, die direkte Instanziierung von Komponenten stets mit Make oder MakeAndInitialize vorzunehmen.

So erstellen und instanziieren Sie eine einfache Protokollierungskomponente

  1. Erstellen Sie in Visual Studio ein Projekt der Win32-Konsolenanwendung. Geben Sie dem Projekt einen Namen, z. B. WRLLogger.

  2. Fügen Sie dem Projekt eine Midl-Datei (.idl) hinzu, nennen Sie die Datei ILogger.idl, und fügen Sie 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] LPCWSTR text);
    }
    
  3. Ersetzen Sie den Inhalt von WRLLogger.cpp durch folgenden Code.

    #include "stdafx.h"
    #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.
    */
    

So behandeln Sie Konstruktionsfehler für die grundlegende Protokollierungskomponente

  1. Ersetzen Sie die Definition der CConsoleWriter-Klasse durch folgenden Code. Diese Version enthält eine private Zeichenfolgenmembervariable und überschreibt die RuntimeClass::RuntimeClassInitialize-Methode. RuntimeClassInitialize verursacht einen Fehler, wenn der Aufruf von SHStrDup einen Fehler verursacht.

    // 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. Ersetzen Sie die Definition von wmain durch folgenden Code. Diese Version instanziiert das CConsoleWriter-Objekt mit MakeAndInitialize und überprüft das HRESULT-Ergebnis.

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

Siehe auch

Referenz

Microsoft::WRL::Make

Microsoft::WRL::Details::MakeAndInitialize

Konzepte

Windows Runtime C++ Template Library (WRL)