Gewusst wie: Direktes Instanziieren von WRL-Komponenten

Erfahren Sie, wie Sie die Windows-Runtime C++-Vorlagenbibliothek (WRL)Microsoft::WRL::Make and Microsoft::WRL::D etails::MakeAndInitialize-Funktionen verwenden, um eine Komponente aus dem Modul zu 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 Universelle Windows-Plattform Apps als auch in Desktop-Apps direkt instanziieren.

Informationen zum Verwenden Windows-Runtime C++-Vorlagenbibliothek zum Erstellen einer klassischen COM-Komponente und Instanziieren von einer externen Desktop-App finden Sie unter How to: Create a Classic COM Component.

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 in der Regel HRESULT-Werte anstelle von Ausnahmen verwendet, um Fehler anzugeben, löst ein COM-Typ normalerweise nicht vom Konstruktor aus. MakeAndInitialize ermöglicht es einer Komponente, ihre Konstruktionsargumente über die RuntimeClassInitialize Methode zu überprüfen.) Beide Beispiele definieren eine einfache Loggerschnittstelle und implementieren diese Schnittstelle durch Definieren einer Klasse, die Nachrichten in die Konsole schreibt.

Wichtig

Sie können den new Operator nicht zum Instanziieren Windows-Runtime C++-Vorlagenbibliothekskomponenten verwenden. 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 Win32-Konsolenanwendungsprojekt . Nennen Sie das Projekt, z . B. WRLLogger.

  2. Fügen Sie dem Projekt eine Midl-Datei (IDL-Datei) hinzu, benennen Sie die Datei ILogger.idl, und fügen Sie dann 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. Verwenden Sie den folgenden Code, um den Inhalt von 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.
    */
    

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 schlägt fehl, wenn der Aufruf SHStrDup fehlschlägt.

    // 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. In dieser Version wird MakeAndInitialize das CConsoleWriter Objekt instanziieren und das HRESULT-Ergebnis überprüft.

    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

C++-Vorlagenbibliothek für Windows-Runtime (WRL)
Microsoft::WRL::Make
Microsoft::WRL::D etails::MakeAndInitialize