이 항목에서는 Windows의 일부이든, 타사 구성 요소 공급업체에서 구현하든, 직접 구현하든 , C++/WinRT API를 사용하는 방법을 보여 줍니다.
중요합니다
이 항목의 코드 예제는 짧고 쉽게 사용해 볼 수 있도록 새 Windows 콘솔 애플리케이션(C++/WinRT) 프로젝트를 만들고 코드를 복사하여 재현할 수 있습니다. 그러나 패키지되지 않은 앱에서는 임의의 사용자 지정(타사) Windows 런타임 형식을 사용할 수 없습니다. 이러한 방식으로 Windows 형식만 사용할 수 있습니다.
콘솔 앱에서 사용자 지정(타사) Windows 런타임 유형을 사용하려면, 사용된 사용자 지정 유형의 등록을 확인할 수 있도록 앱에 패키지 정체성을 부여해야 합니다. 자세한 내용은 Windows 애플리케이션 패키징 프로젝트를 참조하세요.
또는 비어 있는 앱(C++/WinRT), 코어 앱(C++/WinRT), 또는 Windows 런타임 구성 요소(C++/WinRT) 프로젝트 템플릿에서 새 프로젝트를 만듭니다. 이러한 앱 형식은 이미 패키지 ID를 가지고 있습니다.
API가 Windows 네임스페이스에 있는 경우
Windows 런타임 API를 사용하는 가장 일반적인 경우입니다. 메타데이터에 정의된 Windows 네임스페이스의 모든 형식에 대해 C++/WinRT는 C++친화적인 동등한 형식(프로젝션된 형식이라고 함)을 정의합니다. 프로젝션된 타입은 Windows 타입과 완전히 같은 정규화된 이름을 가지지만, C++ 구문을 사용하여 C++ winrt 네임스페이스에 배치됩니다. 예를 들어, Windows::Foundation::Uri는 C++/WinRT에서 winrt::Windows::Foundation::Uri로 변환됩니다.
다음은 간단한 코드 예제입니다. 다음 코드 예제를
// main.cpp
#include <winrt/Windows.Foundation.h>
using namespace winrt;
using namespace Windows::Foundation;
int main()
{
winrt::init_apartment();
Uri contosoUri{ L"http://www.contoso.com" };
Uri combinedUri = contosoUri.CombineUri(L"products");
}
포함된 헤더 winrt/Windows.Foundation.h
는 폴더 %WindowsSdkDir%Include<WindowsTargetPlatformVersion>\cppwinrt\winrt\
내에 있는 SDK의 일부입니다. 해당 폴더의 헤더에는 C++/WinRT로 프로젝션된 Windows 네임스페이스 형식이 포함됩니다. 이 예제에서 winrt/Windows.Foundation.h
는 winrt::Windows::Foundation::Uri를 포함하며, 이는 런타임 클래스 Windows::Foundation::Uri에 대한 프로젝션된 형식입니다.
팁 (조언)
Windows 네임스페이스의 형식을 사용하려는 경우 해당 네임스페이스에 해당하는 C++/WinRT 헤더를 포함합니다.
using namespace
지시문은 선택 사항이지만 편리합니다.
위의 코드 예제에서는 C++/WinRT를 초기화한 후, 공개 문서에 설명된 생성자 중 하나인 Uri(String)를 사용하여 winrt::Windows::Foundation::Uri 형식의 값을 스택에 할당합니다. 이러한 가장 일반적인 사용 사례의 경우, 보통 더 할 필요가 없습니다. C++/WinRT 프로젝션된 형식 값이 있으면 모든 멤버가 동일하므로 실제 Windows 런타임 형식의 인스턴스인 것처럼 처리할 수 있습니다.
실제로 예상 값은 프록시 역할을 합니다. 근본적으로 단지 지원 개체를 가리키는 스마트 포인터일 뿐입니다. 프로젝션된 값의 생성자는
contosoUri
값이 범위를 벗어나면 해당 값이 소멸되고 기본 인터페이스에 대한 참조가 해제됩니다. 해당 참조가 마지막으로 남은 기본 Windows Runtime Windows.Foundation.Uri 개체에 대한 참조인 경우, 기본 개체도 소멸됩니다.
팁 (조언)
프로젝션된 형식은 API를 사용할 목적으로 Windows 런타임 형식에 대한 래퍼입니다. 예를 들어 프로젝션된 인터페이스는 Windows 런타임 인터페이스를 감싸는 래퍼입니다.
C++/WinRT 프로젝션 헤더
C++/WinRT에서 Windows 네임스페이스 API를 사용하려면 %WindowsSdkDir%Include<WindowsTargetPlatformVersion>\cppwinrt\winrt
폴더에서 헤더를 포함합니다. 사용하는 각 네임스페이스에 해당하는 헤더를 포함해야 합니다.
예를 들어, Windows::Security::Cryptography::Certificates 네임스페이스에 해당하는 C++/WinRT 형식 정의는 winrt/Windows.Security.Cryptography.Certificates.h
에 상주합니다. 이 헤더를 포함하면 Windows::Security::Cryptography::Certificates 네임스페이스의 모든 형식에 액세스할 수 있습니다.
경우에 따라 하나의 네임스페이스 헤더에 관련 네임스페이스 헤더의 일부가 포함되지만 이 구현 세부 정보에 의존해서는 안 됩니다. 사용하는 네임스페이스의 헤더를 명시적으로 포함합니다.
예를 들어 Certificate::GetCertificateBlob 메서드는 Windows::Storage::Streams::IBuffer 인터페이스를 반환합니다 .
Certificate::GetCertificateBlob 메서드를 호출하기 전에 반환된 winrt/Windows.Storage.Streams.h
에서 수신하고 작동할 수 있도록 네임스페이스 헤더 파일을 포함 해야 합니다.
해당 네임스페이스에서 형식을 사용하기 전에 필요한 네임스페이스 헤더를 포함하는 것을 잊어버리는 것은 빌드 오류의 일반적인 원인입니다.
개체를 통해, 인터페이스를 통해 또는 ABI를 통해 멤버에 액세스
C++/WinRT 프로젝션을 사용하면 Windows 런타임 클래스의 런타임 표현이 기본 ABI 인터페이스에 지나지 않습니다. 그러나 편의상 작성자가 의도한 방식으로 클래스에 대해 코딩할 수 있습니다. 예를 들어, Uri의 ToString 메서드를 마치 클래스의 메서드인 것처럼 호출할 수 있습니다. 실제로는 이것이 별도의 IStringable 인터페이스의 메서드입니다.
WINRT_ASSERT
은 매크로 정의이며 _ASSERTE로 확장됩니다.
Uri contosoUri{ L"http://www.contoso.com" };
WINRT_ASSERT(contosoUri.ToString() == L"http://www.contoso.com/"); // QueryInterface is called at this point.
이 편의성은 적절한 인터페이스에 대한 쿼리를 통해 수행됩니다. 하지만 당신은 항상 통제할 수 있습니다. 약간의 성능 향상을 위해 약간의 편의를 포기하고, 스스로 IStringable 인터페이스를 검색하여 직접 사용할 수 있습니다. 아래 코드 예제에서는 런타임에(일회성 쿼리를 통해) 실제 IStringable 인터페이스 포인터를 가져옵니다. 그 후에는 ToString 호출이 직접적이며, QueryInterface추가 호출을 피합니다.
...
IStringable stringable = contosoUri; // One-off QueryInterface.
WINRT_ASSERT(stringable.ToString() == L"http://www.contoso.com/");
동일한 인터페이스에서 여러 메서드를 호출할 것을 알고 있는 경우 이 기술을 선택할 수 있습니다.
참고로, ABI 수준에서 멤버에 액세스하려면 가능합니다. 아래 코드 예제에서는 C++/WinRT와 ABI간의
#include <Windows.Foundation.h>
#include <unknwn.h>
#include <winrt/Windows.Foundation.h>
using namespace winrt::Windows::Foundation;
int main()
{
winrt::init_apartment();
Uri contosoUri{ L"http://www.contoso.com" };
int port{ contosoUri.Port() }; // Access the Port "property" accessor via C++/WinRT.
winrt::com_ptr<ABI::Windows::Foundation::IUriRuntimeClass> abiUri{
contosoUri.as<ABI::Windows::Foundation::IUriRuntimeClass>() };
HRESULT hr = abiUri->get_Port(&port); // Access the get_Port ABI function.
}
지연된 초기화
C++/WinRT에서 프로젝션된 각 형식에는 특수 C++/WinRT std::nullptr_t 생성자가 있습니다. 그 하나를 제외하고, 기본 생성자를 포함한 모든 프로젝션 형식의 생성자는 백업 Windows 런타임 개체를 생성하고, 그 개체에 대한 스마트 포인터를 제공합니다. 따라서 이 규칙은 초기화되지 않은 지역 변수, 초기화되지 않은 전역 변수 및 초기화되지 않은 멤버 변수와 같이 기본 생성자가 사용되는 모든 위치에 적용됩니다.
반면에 백업 Windows 런타임 개체를 생성하지 않고 프로젝션된 형식의 변수를 생성하려는 경우(나중에 해당 작업을 지연할 수 있도록) 그렇게 할 수 있습니다. 해당 특수 C++/WinRT std::nullptr_t 생성자(C++/WinRT 프로젝션이 모든 런타임 클래스에 삽입)를 사용하여 변수 또는 필드를 선언합니다. 아래 코드 예제에서 해당 특수 생성자를 m_gamerPicBuffer 사용합니다.
#include <winrt/Windows.Storage.Streams.h>
using namespace winrt::Windows::Storage::Streams;
#define MAX_IMAGE_SIZE 1024
struct Sample
{
void DelayedInit()
{
// Allocate the actual buffer.
m_gamerPicBuffer = Buffer(MAX_IMAGE_SIZE);
}
private:
Buffer m_gamerPicBuffer{ nullptr };
};
int main()
{
winrt::init_apartment();
Sample s;
// ...
s.DelayedInit();
}
프로젝션된 형식의 모든 생성자는
이 고려 사항은 기본 생성자를 호출하는 다른 위치(예: 벡터 및 맵)에 영향을 줍니다. 이 코드 예제에서는 빈 앱(C++/WinRT) 프로젝트가 필요합니다.
std::map<int, TextBlock> lookup;
lookup[2] = value;
할당은 새 TextBlock을 생성한 후 즉시 value
로 덮어씁니다. 여기에 치료법이 있습니다.
std::map<int, TextBlock> lookup;
lookup.insert_or_assign(2, value);
기본 생성자가컬렉션에 미치는 영향을 참조하세요.
실수로 초기화를 지연하지 마세요.
실수로 std::nullptr_t 생성자를 호출하지 않도록 주의하세요. 컴파일러의 충돌 해결은 팩터리 생성자보다 우선합니다. 예를 들어 이러한 두 런타임 클래스 정의를 고려합니다.
// GiftBox.idl
runtimeclass GiftBox
{
GiftBox();
}
// Gift.idl
runtimeclass Gift
{
Gift(GiftBox giftBox); // You can create a gift inside a box.
}
상자 안에 있지 않은 선물을 만들어보겠습니다. 이는 초기화되지 않은 선물 상자를 사용하여 생성된 선물입니다. 먼저 잘못된 방법을 살펴보겠습니다. 우리는 GiftBox를 받는 Gift 생성자가 있다는 것을 알고 있습니다. 그러나 Null
// These are *not* what you intended. Doing it in one of these two ways
// actually *doesn't* create the intended backing Windows Runtime Gift object;
// only an empty smart pointer.
Gift gift{ nullptr };
auto gift{ Gift(nullptr) };
여기에서 얻는 것은 초기화되지 않은 선물입니다. 초기화되지 않은 GiftBox에서는 Gift 을 받을 수 없습니다. 이 작업을 수행하는 올바른 방법은 다음과 같습니다.
// Doing it in one of these two ways creates an initialized
// Gift with an uninitialized GiftBox.
Gift gift{ GiftBox{ nullptr } };
auto gift{ Gift(GiftBox{ nullptr }) };
잘못된 예제에서 nullptr
리터럴을 전달하면 지연 초기화 생성자에 유리하게 확인됩니다. 팩토리 생성자를 위해 매개 변수의 형식은 GiftBox이어야 합니다. 올바른 예제와 같이 GiftBox를 명시적으로 지연 초기화하여 전달할 수 있는 옵션이 있습니다.
이 다음 예제는 매개 변수에 std::nullptr_t아니라 GiftBox 형식이 있으므로 정확합니다.
GiftBox giftBox{ nullptr };
Gift gift{ giftBox }; // Calls factory constructor.
리터럴을 nullptr
전달할 때만 모호성이 발생합니다.
실수로 복사 생성하지 마세요.
이 경고는 위에 설명된 '실수로 지연 초기화를 하지 않음' 섹션에서의 것과 유사합니다.
지연 초기화 생성자 외에도 C++/WinRT 프로젝션은 모든 런타임 클래스에 복사 생성자를 삽입합니다. 생성되는 개체와 동일한 형식을 허용하는 단일 매개 변수 생성자입니다. 결과 스마트 포인터는 생성자 매개 변수가 가리키는 것과 동일한 지원 Windows 런타임 개체를 가리킵니다. 결과는 동일한 기저 객체를 가리키는 두 개의 스마트 포인터 객체입니다.
다음은 코드 예제에서 사용할 런타임 클래스 정의입니다.
// GiftBox.idl
runtimeclass GiftBox
{
GiftBox(GiftBox biggerBox); // You can place a box inside a bigger box.
}
만약 우리가 더 큰 GiftBox내에 GiftBox를 만들고 싶어한다고 가정합시다.
GiftBox bigBox{ ... };
// These are *not* what you intended. Doing it in one of these two ways
// copies bigBox's backing-object-pointer into smallBox.
// The result is that smallBox == bigBox.
GiftBox smallBox{ bigBox };
auto smallBox{ GiftBox(bigBox) };
올바른 방법은 활성화 팩토리를 명시적으로 호출하는 것입니다.
GiftBox bigBox{ ... };
// These two ways call the activation factory explicitly.
GiftBox smallBox{
winrt::get_activation_factory<GiftBox, IGiftBoxFactory>().CreateInstance(bigBox) };
auto smallBox{
winrt::get_activation_factory<GiftBox, IGiftBoxFactory>().CreateInstance(bigBox) };
API가 Windows 런타임 구성 요소에서 구현되는 경우
이 섹션은 구성 요소를 직접 작성했는지 또는 공급업체에서 제공했는지에 관계없이 적용됩니다.
비고
C++/WinRT VSIX(Visual Studio 확장) 및 NuGet 패키지(프로젝트 템플릿 및 빌드 지원을 함께 제공)를 설치하고 사용하는 방법에 대한 자세한 내용은 C++/WinRT대한
애플리케이션 프로젝트에서 Windows 런타임 구성 요소의 Windows 런타임 메타데이터(.winmd
) 파일을 참조하고 빌드합니다. 빌드하는 동안 cppwinrt.exe
도구는 구성 요소의 API 표면을 완전히 설명()하거나 투영()하는 표준 C++ 라이브러리를 생성합니다. 즉, 생성된 라이브러리에는 구성 요소에 대해 프로젝트된 형식이 포함됩니다.
그런 다음 Windows 네임스페이스 형식과 마찬가지로 헤더를 포함하고 해당 생성자 중 하나를 통해 프로젝션된 형식을 생성합니다. 애플리케이션 프로젝트의 시작 코드는 런타임 클래스를 등록하고 프로젝션된 형식의 생성자는 RoActivateInstance 를 호출하여 참조된 구성 요소에서 런타임 클래스를 활성화합니다.
#include <winrt/ThermometerWRC.h>
struct App : implements<App, IFrameworkViewSource, IFrameworkView>
{
ThermometerWRC::Thermometer thermometer;
...
};
Windows 런타임 구성 요소에서 구현된 API 사용에 대한 자세한 내용, 코드 및 연습은 C++/WinRT 및 C++/WinRT
API가 소비 프로젝트에서 구현되는 경우
이 섹션의 코드 예제는 항목의 XAML 컨트롤에서 가져왔으며, C++/WinRT 속성에 바인딩됩니다. 해당 항목을 사용하는 동일한 프로젝트에서 구현된 런타임 클래스를 사용하는 자세한 내용, 코드 및 연습은 해당 항목을 참조하세요.
XAML UI에서 사용되는 형식은 XAML과 동일한 프로젝트에 있더라도 런타임 클래스여야 합니다. 이 시나리오에서는 런타임 클래스의 Windows 런타임 메타데이터(.winmd
)에서 프로젝션된 형식을 생성합니다. 헤더를 포함하지만 런타임 클래스의 인스턴스를 생성하는 C++/WinRT 버전 1.0 또는 버전 2.0 방법 중에서 선택할 수 있습니다. 버전 1.0 메서드는 winrt::make을 사용하고; 버전 2.0 메서드는 통일 생성로 알려져 있습니다. 차례로 각각을 살펴보겠습니다.
winrt::make 사용하여 생성
기본값(C++/WinRT 버전 1.0) 메서드로 시작해 보겠습니다. 적어도 해당 패턴에 익숙한 것이 좋습니다. 해당 std::nullptr_t 생성자를 통해 프로젝션된 형식을 생성합니다. 해당 생성자는 초기화를 수행하지 않으므로 다음으로 winrt::make 도우미 함수를 통해 인스턴스에 값을 할당하고 필요한 생성자 인수를 전달해야 합니다. 소비 코드와 동일한 프로젝트에서 구현된 런타임 클래스는 Windows 런타임/COM 활성화를 통해 등록하거나 인스턴스화할 필요가 없습니다.
XAML 컨트롤 을 참조하시고, C++/WinRT 속성에 바인딩하는 전체 과정을 안내해 드립니다. 이 부분에서는 해당 연습의 발췌문을 보여 줍니다.
// MainPage.idl
import "BookstoreViewModel.idl";
namespace Bookstore
{
runtimeclass MainPage : Windows.UI.Xaml.Controls.Page
{
BookstoreViewModel MainViewModel{ get; };
}
}
// MainPage.h
...
struct MainPage : MainPageT<MainPage>
{
...
private:
Bookstore::BookstoreViewModel m_mainViewModel{ nullptr };
};
...
// MainPage.cpp
...
#include "BookstoreViewModel.h"
MainPage::MainPage()
{
m_mainViewModel = winrt::make<Bookstore::implementation::BookstoreViewModel>();
...
}
균일한 구조
C++/WinRT 버전 2.0 이상에서는 사용할 수 있는 최적화된 형태의
XAML 컨트롤 을 참조하시고, C++/WinRT 속성에 바인딩하는 전체 과정을 안내해 드립니다. 이 부분에서는 해당 연습의 발췌문을 보여 줍니다.
균일 생성 대신 winrt::make를 사용하려면 활성화 팩토리가 필요합니다. 생성할 수 있는 좋은 방법은 IDL에 생성자를 추가하는 것입니다.
// MainPage.idl
import "BookstoreViewModel.idl";
namespace Bookstore
{
runtimeclass MainPage : Windows.UI.Xaml.Controls.Page
{
MainPage();
BookstoreViewModel MainViewModel{ get; };
}
}
그런 다음, 아래와 같이 MainPage.h
에서 m_mainViewModel를 선언하고 초기화하세요, 단 한 단계로.
// MainPage.h
...
struct MainPage : MainPageT<MainPage>
{
...
private:
Bookstore::BookstoreViewModel m_mainViewModel;
...
};
}
...
그런 다음 에 있는 MainPage.cpp
생성자에서는 m_mainViewModel = winrt::make<Bookstore::implementation::BookstoreViewModel>();
코드를 사용할 필요가 없습니다.
자세한 내용과 코드 예제는 "균일한 생성에 옵트인하고 직접 구현에 접근하기" 주제의 및을 참조하세요.
프로젝션된 형식 및 인터페이스 인스턴스화 및 반환
다음은 소비 프로젝트에서 프로젝션된 형식 및 인터페이스가 어떻게 표시되는지에 대한 예입니다. 프로젝션된 형식(예: 이 예제의 형식)은 도구로 생성되며 직접 작성하는 형식이 아닙니다.
struct MyRuntimeClass : MyProject::IMyRuntimeClass, impl::require<MyRuntimeClass,
Windows::Foundation::IStringable, Windows::Foundation::IClosable>
MyRuntimeClass 는 프로젝션된 형식입니다. 프로젝션된 인터페이스에는 IMyRuntimeClass, IStringable 및 IClosable이 포함됩니다. 이 항목에서는 프로젝션된 형식을 인스턴스화할 수 있는 다양한 방법을 보여 했습니다. 이것은 MyRuntimeClass을 예로 사용하는 미리 알림과 요약입니다.
// The runtime class is implemented in another compilation unit (it's either a Windows API,
// or it's implemented in a second- or third-party component).
MyProject::MyRuntimeClass myrc1;
// The runtime class is implemented in the same compilation unit.
MyProject::MyRuntimeClass myrc2{ nullptr };
myrc2 = winrt::make<MyProject::implementation::MyRuntimeClass>();
- 프로젝션된 형식의 모든 인터페이스의 멤버에 액세스할 수 있습니다.
- 프로젝션된 형식을 호출자에게 반환할 수 있습니다.
- 프로젝션된 형식 및 인터페이스는 winrt::Windows::Foundation::IUnknown에서 파생된다. 따라서 프로젝션된 형식 또는 인터페이스에서 IUnknown::as를 호출하여 다른 프로젝션된 인터페이스를 쿼리할 수 있으며, 이를 사용하거나 호출자에게 반환할 수 있습니다. 은 멤버 함수로서 QueryInterface처럼 작동합니다.
void f(MyProject::MyRuntimeClass const& myrc)
{
myrc.ToString();
myrc.Close();
IClosable iclosable = myrc.as<IClosable>();
iclosable.Close();
}
활성화 공장
C++/WinRT 개체를 만드는 편리하고 직접적인 방법은 다음과 같습니다.
using namespace winrt::Windows::Globalization::NumberFormatting;
...
CurrencyFormatter currency{ L"USD" };
때로는 활성화 팩토리를 직접 만든 다음, 편의에 따라 개체를 생성하려는 경우가 있을 수 있습니다. 다음은, winrt::get_activation_factory 함수 템플릿을 사용하는 방법을 보여주는 몇 가지 예입니다.
using namespace winrt::Windows::Globalization::NumberFormatting;
...
auto factory = winrt::get_activation_factory<CurrencyFormatter, ICurrencyFormatterFactory>();
CurrencyFormatter currency = factory.CreateCurrencyFormatterCode(L"USD");
using namespace winrt::Windows::Foundation;
...
auto factory = winrt::get_activation_factory<Uri, IUriRuntimeClassFactory>();
Uri uri = factory.CreateUri(L"http://www.contoso.com");
위의 두 예제의 클래스는 Windows 네임스페이스의 형식입니다. 다음 예제에서 ThermometerWRC::Thermometer 는 Windows 런타임 구성 요소에 구현된 사용자 지정 형식입니다.
auto factory = winrt::get_activation_factory<ThermometerWRC::Thermometer>();
ThermometerWRC::Thermometer thermometer = factory.ActivateInstance<ThermometerWRC::Thermometer>();
멤버/형식 모호성
멤버 함수의 이름이 형식과 같으면 모호성이 있습니다. 멤버 함수에서의 C++ 비정규화 이름 조회 규칙은 네임스페이스를 검색하기 전에 클래스를 먼저 검색하도록 합니다. 대체 실패는 SFINAE(오류) 규칙이 적용되지 않습니다(함수 템플릿의 오버로드 확인 중에 적용됨). 따라서 클래스 내의 이름이 이해가 되지 않는 경우 컴파일러는 더 나은 일치 항목을 계속 찾지 않고 단순히 오류를 보고합니다.
struct MyPage : Page
{
void DoWork()
{
// This doesn't compile. You get the error
// "'winrt::Windows::Foundation::IUnknown::as':
// no matching overloaded function found".
auto style{ Application::Current().Resources().
Lookup(L"MyStyle").as<Style>() };
}
}
위에서 컴파일러는 C++/WinRT에서 멤버 함수인 FrameworkElement.Style()를 IUnknown::as의 템플릿 매개 변수로 전달한다고 생각합니다. 해결 방법은
struct MyPage : Page
{
void DoWork()
{
// One option is to fully-qualify it.
auto style{ Application::Current().Resources().
Lookup(L"MyStyle").as<Windows::UI::Xaml::Style>() };
// Another is to force it to be interpreted as a struct name.
auto style{ Application::Current().Resources().
Lookup(L"MyStyle").as<struct Style>() };
// If you have "using namespace Windows::UI;", then this is sufficient.
auto style{ Application::Current().Resources().
Lookup(L"MyStyle").as<Xaml::Style>() };
// Or you can force it to be resolved in the global namespace (into which
// you imported the Windows::UI::Xaml namespace when you did
// "using namespace Windows::UI::Xaml;".
auto style = Application::Current().Resources().
Lookup(L"MyStyle").as<::Style>();
}
}
정규화되지 않은 이름을 조회할 때, 이름 뒤에 ::
가 붙는 경우 특별한 예외가 적용되며, 이 경우 함수, 변수, 그리고 열거형 값은 무시됩니다. 이렇게 하면 다음과 같은 작업을 수행할 수 있습니다.
struct MyPage : Page
{
void DoSomething()
{
Visibility(Visibility::Collapsed); // No ambiguity here (special exception).
}
}
Visibility()
호출은 UIElement.Visibility 멤버 함수 이름으로 해석됩니다. 그러나 매개 변수 Visibility::Collapsed
는 Visibility
단어 뒤에 ::
와 함께 따라오므로 메서드 이름이 무시되고, 컴파일러가 열거형 클래스를 찾습니다.
중요 API
- QueryInterface 함수
- RoActivateInstance 함수
- Windows::Foundation::Uri 클래스
- winrt::get_activation_factory 함수 템플릿
- winrt::make 함수 템플릿
- winrt::Windows::Foundation::IUnknown 구조체