C++/WinRT를 사용한 Windows 런타임 구성 요소Windows Runtime components with C++/WinRT

이 항목에서는 c + +/Winrt 를 사용 하 여 — Windows 런타임 언어를 사용 하 여 빌드된 유니버설 Windows 앱에서 호출할 수 있는 구성 요소를 Windows 런타임 구성 요소를 만들고 사용 하는 방법을 보여 줍니다.This topic shows how to use C++/WinRT to create and consume a Windows Runtime component—a component that's callable from a Universal Windows app built using any Windows Runtime language.

C + +/WinRT.에서 Windows 런타임 구성 요소를 작성 하는 데는 몇 가지 이유가 있습니다.There are several reasons for building a Windows Runtime component in C++/WinRT.

  • 복잡 하거나 계산 집약적인 작업에서 c + +의 성능 이점을 누릴 수 있습니다.To enjoy the performance advantage of C++ in complex or computationally intensive operations.
  • 이미 작성 되 고 테스트 된 표준 c + + 코드를 다시 사용 합니다.To reuse standard C++ code that's already written and tested.
  • 로 작성 된 UWP (유니버설 Windows 플랫폼) 앱에 Win32 기능을 노출 하려면 (예: c #)To expose Win32 functionality to a Universal Windows Platform (UWP) app written in, for example, C#.

일반적으로 c + +/WinRT 구성 요소를 제작할 때 다른 패키지의 코드에서 데이터를 전달 하는 ABI (응용 프로그램 이진 인터페이스) 경계를 제외 하 고 표준 c + + 라이브러리의 형식 및 기본 제공 형식을 사용할 수 있습니다 .winmd .In general, when you author your C++/WinRT component, you can use types from the standard C++ library, and built-in types, except at the application binary interface (ABI) boundary where you're passing data to and from code in another .winmd package. ABI에서 Windows 런타임 형식을 사용 합니다.At the ABI, use Windows Runtime types. 또한 c + +/WinRT 코드에서 대리자 및 이벤트와 같은 형식을 사용 하 여 구성 요소에서 발생 하 고 다른 언어로 처리 될 수 있는 이벤트를 구현 합니다.In addition, in your C++/WinRT code, use types such as delegate and event to implement events that can be raised from your component and handled in another language. C + +/Winrtd에 대 한 자세한 내용은 c + +/vb 를 참조 하세요.See C++/WinRT for more info about C++/WinRT.

이 항목의 나머지 부분에서는 c + +/WinRT에서 Windows 런타임 구성 요소를 작성 한 다음 응용 프로그램에서 사용 하는 방법을 안내 합니다.The remainder of this topic walks you through how to author a Windows Runtime component in C++/WinRT, and then how to consume it from an application.

이 항목에서 빌드할 Windows 런타임 구성 요소는 온도계를 나타내는 런타임 클래스를 포함 합니다.The Windows Runtime component that you'll build in this topic contains a runtime class representing a thermometer. 또한이 항목에서는 온도계 런타임 클래스를 사용 하는 핵심 앱을 보여 주고 온도를 조정 하는 함수를 호출 합니다.The topic also demonstrates a Core App that consumes the thermometer runtime class, and calls a function to adjust the temperature.

참고

프로젝트 템플릿 및 빌드 지원을 함께 제공하는 C++/WinRT Visual Studio 확장(VSIX) 및 NuGet 패키지를 설치하고 사용하는 방법에 대한 자세한 내용은 Visual Studio의 C++/WinRT 지원을 참조하세요.For info about installing and using the C++/WinRT Visual Studio Extension (VSIX) and the NuGet package (which together provide project template and build support), see Visual Studio support for C++/WinRT.

중요

C++/WinRT를 사용해 런타임 클래스를 사용하거나 작성하는 방법을 더욱 쉽게 이해할 수 있는 필수 개념과 용어에 대해서는 C++/WinRT를 통한 API 사용C++/WinRT를 통한 API 작성을 참조하세요.For essential concepts and terms that support your understanding of how to consume and author runtime classes with C++/WinRT, see Consume APIs with C++/WinRT and Author APIs with C++/WinRT.

Windows 런타임 구성 요소 만들기 (ThermometerWRC)Create a Windows Runtime component (ThermometerWRC)

먼저 Microsoft Visual Studio에서 새 프로젝트를 만듭니다.Begin by creating a new project in Microsoft Visual Studio. Windows 런타임 구성 요소 (c + +/WinRT) 프로젝트를 만들고 이름을 ThermometerWRC ("온도계 Windows 런타임 구성 요소"의 경우)로 만듭니다.Create a Windows Runtime Component (C++/WinRT) project, and name it ThermometerWRC (for "thermometer Windows Runtime component"). 솔루션 및 프로젝트를 같은 디렉터리에 배치를 선택하지 않아야 합니다.Make sure that Place solution and project in the same directory is unchecked. 일반적으로 사용 가능한 최신(미리 보기 아님) 버전의 Windows SDK를 대상으로 합니다.Target the latest generally-available (that is, not preview) version of the Windows SDK. ThermometerWRC 프로젝트 이름을 지정 하면이 항목의 나머지 단계를 가장 쉽게 수행할 수 있습니다.Naming the project ThermometerWRC will give you the easiest experience with the rest of the steps in this topic.

아직 프로젝트를 빌드하지 마세요.Don't build the project yet.

새로 만든 프로젝트에는 Class.idl이라는 이름의 파일이 포함되어 있습니다.The newly-created project contains a file named Class.idl. 솔루션 탐색기에서 Thermometer.idl 파일의 이름을 바꿉니다(.idl 파일의 이름을 바꾸면 자동으로 종속 .h.cpp 파일의 이름도 바뀜).In Solution Explorer, rename that file Thermometer.idl (renaming the .idl file automatically renames the dependent .h and .cpp files, too). Thermometer.idl의 콘텐츠를 아래 목록으로 바꿉니다.Replace the contents of Thermometer.idl with the listing below.

// Thermometer.idl
namespace ThermometerWRC
{
    runtimeclass Thermometer
    {
        Thermometer();
        void AdjustTemperature(Single deltaFahrenheit);
    };
}

파일을 저장합니다.Save the file. 프로젝트는 현재 완료 될 때까지 빌드되지 않지만 이제는 온도계 런타임 클래스를 구현 하는 소스 코드 파일을 생성 하기 때문에 빌드를 수행 하는 것이 좋습니다.The project won't build to completion at the moment, but building now is a useful thing to do because it generates the source code files in which you'll implement the Thermometer runtime class. 따라서 계속해서 지금 빌드합니다(이 단계에서 표시될 것으로 예상되는 빌드 오류는 발견되는 Class.hClass.g.h로 처리해야 함).So go ahead and build now (the build errors you can expect to see at this stage have to do with Class.h and Class.g.h not being found).

빌드 프로세스에서 midl.exe 도구가 실행되어 구성 요소의 Windows 런타임 메타데이터 파일(\ThermometerWRC\Debug\ThermometerWRC\ThermometerWRC.winmd)을 생성합니다.During the build process, the midl.exe tool is run to create your component's Windows Runtime metadata file (which is \ThermometerWRC\Debug\ThermometerWRC\ThermometerWRC.winmd). 그런 다음, cppwinrt.exe 도구가 실행되어(-component 옵션과 함께) 구성 요소를 작성하도록 지원하는 원본 코드 파일을 생성합니다.Then, the cppwinrt.exe tool is run (with the -component option) to generate source code files to support you in authoring your component. 이러한 파일에는 IDL에 선언 된 온도계 런타임 클래스 구현을 시작 하기 위한 스텁이 포함 되어 있습니다.These files include stubs to get you started implementing the Thermometer runtime class that you declared in your IDL. 이 스텁이 \ThermometerWRC\ThermometerWRC\Generated Files\sources\Thermometer.hThermometer.cpp입니다.Those stubs are \ThermometerWRC\ThermometerWRC\Generated Files\sources\Thermometer.h and Thermometer.cpp.

프로젝트 노드를 마우스 오른쪽 단추로 클릭하고 파일 탐색기에서 폴더 열기를 클릭합니다.Right-click the project node and click Open Folder in File Explorer. 파일 탐색기에서 프로젝트 폴더가 열립니다.This opens the project folder in File Explorer. 여기에서 \ThermometerWRC\ThermometerWRC\Generated Files\sources\ 폴더에서 스텁 파일 Thermometer.hThermometer.cpp를 복사하여 프로젝트 파일을 포함하는 폴더인 \ThermometerWRC\ThermometerWRC\에 붙여넣고 대상에서 파일을 바꿉니다.There, copy the stub files Thermometer.h and Thermometer.cpp from the folder \ThermometerWRC\ThermometerWRC\Generated Files\sources\ and into the folder that contains your project files, which is \ThermometerWRC\ThermometerWRC\, and replace the files in the destination. 이제 Thermometer.hThermometer.cpp를 열고 런타임 클래스를 구현합니다.Now, let's open Thermometer.h and Thermometer.cpp and implement our runtime class. 에서 Thermometer.h 온도계의 구현 (팩터리 구현이아님 )에 새 개인 멤버를 추가 합니다.In Thermometer.h, add a new private member to the implementation (not the factory implementation) of Thermometer.

// Thermometer.h
...
namespace winrt::ThermometerWRC::implementation
{
    struct Thermometer : ThermometerT<Thermometer>
    {
        ...

    private:
        float m_temperatureFahrenheit { 0.f };
    };
}
...

에서 Thermometer.cpp 아래 목록에 표시 된 것 처럼 AdjustTemperature 메서드를 구현 합니다.In Thermometer.cpp, implement the AdjustTemperature method as shown in the listing below.

// Thermometer.cpp
...
namespace winrt::ThermometerWRC::implementation
{
    void Thermometer::AdjustTemperature(float deltaFahrenheit)
    {
        m_temperatureFahrenheit += deltaFahrenheit;
    }
}

또한 두 파일에서 static_assert를 삭제해야 합니다.You'll also need to delete the static_assert from both files.

경고 메시지로 인해 빌드가 중단되는 경우에는 경고를 해결하거나 프로젝트 속성 C/C++ > 일반 > 경고를 오류로 처리아니요(/WX-) 로 설정한 후 프로젝트를 다시 빌드합니다.If any warnings prevent you from building, then either resolve them or set the project property C/C++ > General > Treat Warnings As Errors to No (/WX-), and build the project again.

핵심 앱 (ThermometerCoreApp)을 만들어 Windows 런타임 구성 요소 테스트Create a Core App (ThermometerCoreApp) to test the Windows Runtime component

이제 ThermometerWRC 솔루션 또는 새 프로젝트에서 새 프로젝트를 만듭니다.Now create a new project (either in your ThermometerWRC solution, or in a new one). 핵심 앱 (c + +/WinRT) 프로젝트를 만들고 이름을 ThermometerCoreApp로 합니다.Create a Core App (C++/WinRT) project, and name it ThermometerCoreApp. 두 프로젝트가 동일한 솔루션에 있는 경우 ThermometerCoreApp 를 시작 프로젝트로 설정 합니다.Set ThermometerCoreApp as the startup project if the two projects are in the same solution.

참고

앞에서 설명한 것 처럼 Windows 런타임 구성 요소에 대 한 Windows 런타임 메타 데이터 파일 (이름이 ThermometerWRC인 프로젝트)이 폴더에 만들어집니다 \ThermometerWRC\Debug\ThermometerWRC\ .As mentioned earlier, the Windows Runtime metadata file for your Windows Runtime component (whose project you named ThermometerWRC) is created in the folder \ThermometerWRC\Debug\ThermometerWRC\. 해당 경로의 첫 번째 세그먼트는 솔루션 파일이 포함된 폴더의 이름입니다. 다음 세그먼트는 Debug라는 하위 디렉터리입니다. 마지막 세그먼트는 Windows 런타임 구성 요소에 대해 이름이 지정된 하위 디렉터리입니다.The first segment of that path is the name of the folder that contains your solution file; the next segment is the subdirectory of that named Debug; and the last segment is the subdirectory of that named for your Windows Runtime component. 프로젝트 이름을 ThermometerWRC로 지정한 경우 메타 데이터 파일은 폴더에 \<YourProjectName>\Debug\<YourProjectName>\ 있습니다.If you didn't name your project ThermometerWRC, then your metadata file will be in the folder \<YourProjectName>\Debug\<YourProjectName>\.

이제 핵심 앱 프로젝트 (ThermometerCoreApp)에서 참조를 추가 하 고, \ThermometerWRC\Debug\ThermometerWRC\ThermometerWRC.winmd 두 프로젝트가 동일한 솔루션에 있는 경우 프로젝트 간 참조를 탐색 하거나 추가 합니다.Now, in your Core App project (ThermometerCoreApp), add a reference, and browse to \ThermometerWRC\Debug\ThermometerWRC\ThermometerWRC.winmd (or add a project-to-project reference, if the two projects are in the same solution). 추가, 확인을 차례로 클릭합니다.Click Add, and then OK. 이제 ThermometerCoreApp을 빌드합니다.Now build ThermometerCoreApp. 페이로드 파일이 없다는 오류가 표시 되는 경우 readme.txt Windows 런타임 구성 요소 프로젝트에서 해당 파일을 제외 하 고 다시 빌드한 다음 ThermometerCoreApp를 다시 빌드합니다.In the unlikely event that you see an error that the payload file readme.txt doesn't exist, exclude that file from the Windows Runtime component project, rebuild it, then rebuild ThermometerCoreApp.

빌드 프로세스에서 cppwinrt.exe 도구가 실행되면서 참조된 .winmd 파일을 원본 코드 파일로 처리합니다. 이 원본 코드 파일에는 구성 요소를 사용할 때 지원할 목적으로 프로젝션된 형식이 포함되어 있습니다.During the build process, the cppwinrt.exe tool is run to process the referenced .winmd file into source code files containing projected types to support you in consuming your component. 구성 요소의 런타임 클래스에 맞게 프로젝션된 형식의 헤더(ThermometerWRC.h)가 \ThermometerCoreApp\ThermometerCoreApp\Generated Files\winrt\ 폴더로 생성됩니다.The header for the projected types for your component's runtime classes—named ThermometerWRC.h—is generated into the folder \ThermometerCoreApp\ThermometerCoreApp\Generated Files\winrt\.

이 헤더를 App.cpp에 추가합니다.Include that header in App.cpp.

// App.cpp
...
#include <winrt/ThermometerWRC.h>
...

또한에서 App.cpp 다음 코드를 추가 하 여, 프로젝션 된 형식의 기본 생성자를 사용 하 여 온도계 개체를 인스턴스화하고 온도계 개체에서 메서드를 호출 합니다.Also in App.cpp, add the following code to instantiate a Thermometer object (using the projected type's default constructor), and call a method on the thermometer object.

struct App : implements<App, IFrameworkViewSource, IFrameworkView>
{
    ThermometerWRC::Thermometer m_thermometer;
    ...
    
    void OnPointerPressed(IInspectable const &, PointerEventArgs const & args)
    {
        m_thermometer.AdjustTemperature(1.f);
        ...
    }
    ...
};

창을 클릭할 때마다 온도계 개체의 온도가 증가 합니다.Each time you click the window, you increment the thermometer object's temperature. 코드를 단계별로 실행 하 여 응용 프로그램이 Windows 런타임 구성 요소를 정말로 호출 하 고 있는지 확인 하려는 경우 중단점을 설정할 수 있습니다.You can set breakpoints if you want to step through the code to confirm that the application really is calling into the Windows Runtime component.

다음 단계Next steps

C + +/WinRT Windows 런타임 구성 요소에 더 많은 기능 또는 새로운 Windows 런타임 형식을 추가 하려면 위에 표시 된 것과 동일한 패턴을 따를 수 있습니다.To add even more functionality, or new Windows Runtime types, to your C++/WinRT Windows Runtime component, you can follow the same patterns shown above. 먼저 IDL을 사용 하 여 노출 하려는 기능을 정의 합니다.First, use IDL to define the functionality you want to expose. 그런 다음 Visual Studio에서 프로젝트를 빌드하여 스텁 구현을 생성 합니다.Then build the project in Visual Studio to generate a stub implementation. 그런 다음 구현을 적절 하 게 완료 합니다.And then complete the implementation as appropriate. IDL에서 정의 하는 메서드, 속성 및 이벤트는 Windows 런타임 구성 요소를 사용 하는 응용 프로그램에 표시 됩니다.Any methods, properties, and events that you define in IDL are visible to the application that consumes your Windows Runtime Component. IDL에 대 한 자세한 내용은 Microsoft 인터페이스 정의 언어 3.0 소개를 참조 하세요.For more info about IDL, see Introduction to Microsoft Interface Definition Language 3.0.

Windows 런타임 구성 요소에 이벤트를 추가 하는 방법에 대 한 예제는 c + +/WinRT의 Author 이벤트를 참조 하세요.For an example of how to add an event to your Windows Runtime Component, see Author events in C++/WinRT.

문제 해결Troubleshooting

증상Symptom 해결책Remedy
C++/WinRT 앱에서 XAML을 사용하는 C# Windows 런타임 구성 요소를 사용할 때 컴파일러는 " 'MyNamespace_XamlTypeInfo': is not a member of 'winrt::MyNamespace' " 형식의 오류를 발생합니다. —여기서 MyNamespace는 Windows 런타임 구성 요소의 네임스페이스 이름입니다.In a C++/WinRT app, when consuming a C# Windows Runtime component that uses XAML, the compiler produces an error of the form "'MyNamespace_XamlTypeInfo': is not a member of 'winrt::MyNamespace'"—where MyNamespace is the name of the Windows Runtime component's namespace. 사용하는 C++/WinRT 앱의 pch.h에서 MyNamespace를 적절하게 대체하는 #include <winrt/MyNamespace.MyNamespace_XamlTypeInfo.h>—를 추가합니다.In pch.h in the consuming C++/WinRT app, add #include <winrt/MyNamespace.MyNamespace_XamlTypeInfo.h>—replacing MyNamespace as appropriate.