방법: 직접 WRL 구성 요소 인스턴스화

Windows 런타임 C++ 템플릿 라이브러리(WRL)Microsoft::WRL::MakeMicrosoft::WRL::D etails::MakeAndInitialize 함수를 사용하여 이를 정의하는 모듈에서 구성 요소를 인스턴스화하는 방법을 알아봅니다.

구성 요소를 직접 인스턴스화하면 클래스 팩터리 또는 기타 메커니즘이 필요하지 않을 때 오버헤드를 줄일 수 있습니다. 유니버설 Windows 플랫폼 앱과 데스크톱 앱 모두에서 구성 요소를 직접 인스턴스화할 수 있습니다.

Windows 런타임 C++ 템플릿 라이브러리를 사용하여 클래식 COM 구성 요소를 만들고 외부 데스크톱 앱에서 인스턴스화하는 방법을 알아보려면 방법: 클래식 COM 구성 요소 만들기를 참조하세요.

이 문서에서는 두 가지 예를 보여 줍니다. 첫 번째 예제에서는 함수를 Make 사용하여 구성 요소를 인스턴스화합니다. 두 번째 예제에서는 함수를 MakeAndInitialize 사용하여 생성 중에 실패할 수 있는 구성 요소를 인스턴스화합니다. COM은 일반적으로 예외 대신 HRESULT 값을 사용하여 오류를 나타내기 때문에 COM 형식은 일반적으로 해당 생성자에서 throw되지 않습니다. MakeAndInitialize 를 사용하면 구성 요소가 메서드를 통해 생성 인수의 유효성을 검사할 수 RuntimeClassInitialize 있습니다.) 두 예제 모두 기본 로거 인터페이스를 정의하고 콘솔에 메시지를 쓰는 클래스를 정의하여 해당 인터페이스를 구현합니다.

Important

연산자를 new 사용하여 Windows 런타임 C++ 템플릿 라이브러리 구성 요소를 인스턴스화할 수 없습니다. 따라서 항상 구성 요소를 직접 사용 Make 하거나 MakeAndInitialize 인스턴스화하는 것이 좋습니다.

기본 로거 구성 요소를 만들고 인스턴스화하려면

  1. Visual Studio에서 Win32 콘솔 애플리케이션 프로젝트를 만듭니다. 프로젝트 이름을 WRLLogger와 같이 지정합니다.

  2. 프로젝트에 Midl 파일(.idl) 파일을 추가하고 파일 ILogger.idl이름을 지정한 다음 다음 코드를 추가합니다.

    import "ocidl.idl";
    
    // Prints text to the console.
    [uuid(AFDB9683-F18A-4B85-90D1-B6158DAFA46C)]
    interface ILogger : IUnknown
    {
        HRESULT Log([in] LPCWSTR text);
    }
    
  3. 다음 코드를 사용하여 .의 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.
    */
    

기본 로거 구성 요소의 생성 실패를 처리하려면

  1. 클래스의 정의를 CConsoleWriter 바꾸려면 다음 코드를 사용합니다. 이 버전은 프라이빗 문자열 멤버 변수를 보유하고 메서드를 재정의 RuntimeClass::RuntimeClassInitialize 합니다. RuntimeClassInitialize 호출이 실패하면 실패합니다 SHStrDup .

    // 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. 다음 코드를 wmain사용하여 . 이 버전은 개체를 CConsoleWriter 인스턴스화하고 HRESULT 결과를 검사 사용합니다MakeAndInitialize.

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

참고 항목

Windows 런타임 C++ 템플릿 라이브러리(WRL)
Microsoft::WRL::Make
Microsoft::WRL::D etails::MakeAndInitialize