Microsoft 인터페이스 정의 언어 3.0 소개
MIDL(Microsoft Interface Definition Language) 3.0은 IDL(Interface Definition Language) 파일(.idl
파일) 내에서 Windows 런타임 형식을 정의하기 위한 간소화된 최신 구문입니다. 이 새로운 구문은 C, C++, C#및/또는 Java를 경험하는 모든 사용자에게 친숙합니다. MIDL 3.0은 C++/WinRT 런타임 클래스를 정의하는 특히 편리한 방법이며, 이전 버전의 IDL보다 훨씬 간결합니다(디자인 길이를 3분의 2로 줄이고 적절한 기본값을 사용하여 특성으로 데코레이팅할 필요성을 줄임).
MIDL 3.0의 모양은 다음과 같습니다. 이 예제에서는 사용할 수 있는 대부분의 언어 구문 요소를 보여 줍니다.
// Photo.idl
namespace PhotoEditor
{
delegate void RecognitionHandler(Boolean arg); // delegate type, for an event.
runtimeclass Photo : Windows.UI.Xaml.Data.INotifyPropertyChanged // interface.
{
Photo(); // constructors.
Photo(Windows.Storage.StorageFile imageFile);
String ImageName{ get; }; // read-only property.
Single SepiaIntensity; // read-write property.
Windows.Foundation.IAsyncAction StartRecognitionAsync(); // (asynchronous) method.
event RecognitionHandler ImageRecognized; // event.
}
}
MIDL 3.0의 구문은 형식을 정의하는 midl.exe
버전 8.01.0622 이상, /winrt
스위치와 함께 사용됨)이 필요합니다.
메모
Windows 런타임 통합 참조(
MIDL 1.0, 2.0 및 3.0
IDL(인터페이스 정의 언어)은 DCE/RPC(분산 컴퓨팅 환경/원격 프로시저 호출) 시스템에서 시작되었습니다. 원래 MIDL 1.0 COM 인터페이스 및 코클래스를 정의하기 위한 향상된 기능을 갖춘 DCE/RPC IDL입니다.
그런 다음 업데이트된 MIDL 2.0 구문(MIDLRT라고도 함)이 Microsoft 내에서 개발되어 Windows 플랫폼용 Windows 런타임 API를 선언했습니다. Windows SDK 폴더 %WindowsSdkDir%Include<WindowsTargetPlatformVersion>\winrt
보면 MIDL 2.0 구문으로 작성된 .idl
파일의 예제가 표시됩니다. 이러한 ABI(애플리케이션 이진 인터페이스) 형식으로 선언된 기본 제공 Windows 런타임 API입니다. 이러한 파일은 주로 도구를 사용하기 위해 존재합니다. 이 형식에서는 이러한 API를 작성하거나 사용하지 않습니다(매우 낮은 수준의 코드를 작성하지 않는 한).
또한 클래식 MIDLRTMIDL 3.0으로
MIDL 3.0은 Windows 런타임 API를 선언하는 것이 목적인 훨씬 간단하고 최신 구문입니다. 또한 프로젝트에서 특히 C++/WinRT 런타임 클래스를 %WindowsSdkDir%Include<WindowsTargetPlatformVersion>\cppwinrt\winrt
폴더 내의 SDK에 포함됩니다.
MIDL 3.0의 사용 사례
일반적으로 모든 Windows 런타임 API는 모든 Windows 런타임 언어 프로젝션에서 사용할 수 있도록 설계되었습니다. 이 작업은 Windows 런타임 API와 Windows 런타임 형식을 단독으로 전달하도록 선택하여 부분적으로 수행됩니다. Windows 런타임 API와 원시 COM 인터페이스를 전달하는 것은 유효한 디자인 결정이지만, 이렇게 하면 특정 Windows 런타임 API의 소비자가 C++ 애플리케이션으로 제한됩니다. 이 기술은 상호 운용 시나리오(예: Direct3D와 XAML 간에 상호 운용하는 경우)에서 확인할 수 있습니다. Direct3D는 그림에 있으므로 시나리오는 반드시 C++ 애플리케이션으로 좁혀집니다. 따라서 COM 인터페이스가 필요한 API는 내재된 것 이상으로 추가적인 제한을 적용하지 않습니다. 예를 들어 C++ 애플리케이션은 IDXGISwapChain 인터페이스 포인터를 가져온 다음 ISwapChainPanelNative::SetSwapChain 메서드전달할 수 있습니다. 예를 들어 C# 애플리케이션은 시작할 IDXGISwapChain 가져올 수 없으므로 이러한 이유로 해당 메서드를 사용할 수 없습니다. 이러한 interop 관련 예외는 windows.ui.xaml.media.dxinterop.h
같은 interop 헤더에 있습니다.
C++를 넘어 Windows 런타임 언어 프로젝션에 노출하려는 COM 구성 요소의 기능 또는 기능이
정의 구조 및 명령줄에서 midl.exe 호출
MIDL 3.0 정의의 주요 조직 개념은 네임스페이스, 형식 및 멤버입니다. MIDL 3.0 소스 파일(.idl
파일)에는 형식 및/또는 하위 네임스페이스인 하나 이상의 네임스페이스가 포함되어 있습니다. 각 형식에는 0개 이상의 멤버가 포함됩니다.
- 클래스, 인터페이스, 구조체 및 열거형은 형식입니다.
- 메서드, 속성, 이벤트 및 필드는 멤버의 예입니다.
MIDL 3.0 소스 파일을 컴파일하는 경우 컴파일러(midl.exe
)는 Windows 런타임 메타데이터 파일(일반적으로 .winmd
파일)을 내보냅니다.
// Bookstore.idl
namespace Bookstore
{
runtimeclass BookSku : Windows.UI.Xaml.Data.INotifyPropertyChanged
{
BookSku();
BookSku(Single price, String authorName, String coverImagePath, String title);
Single Price;
String AuthorName{ get; };
Windows.UI.Xaml.Media.ImageSource CoverImage{ get; };
String CoverImagePath{ get; };
String Title{ get; };
Boolean Equals(BookSku other);
void ApplyDiscount(Single percentOff);
}
}
Windows 런타임 형식의 네임스페이스는 형식 이름의 일부가 되므로 위의 예제에서는 Bookstore.BookSku런타임 클래스를 정의합니다. 네임스페이스도 표현하지 않고는 BookSku 표현하는 언어 독립적 방법이 없습니다.
이 클래스는 Windows.UI.Xaml.Data.INotifyPropertyChanged 인터페이스를 구현합니다. 또한 클래스에는 두 개의 생성자, 읽기-쓰기 속성(Price), 일부 읽기 전용 속성(AuthorNameTitle) 및 Equals 및 ApplyDiscount라는 두 개의 메서드가 포함됩니다. float
팁
Visual Studio는 C++/WinRT VSIX(Visual Studio Extension)를 통해 MIDL 3.0을 컴파일하는 데 가장 적합한 환경을 제공합니다. C++/WinRT 및 VSIX대한
그러나 명령줄에서 MIDL 3.0을 컴파일할 수도 있습니다. 이 예제의 소스 코드가 Bookstore.idl
파일에 저장된 경우 아래 명령을 실행할 수 있습니다. 필요한 경우 명령에 사용된 SDK 버전 번호(10.0.17134.0)를 업데이트할 수 있습니다.
midl /winrt /metadata_dir "%WindowsSdkDir%References\10.0.17134.0\windows.foundation.foundationcontract\3.0.0.0" /h "nul" /nomidl /reference "%WindowsSdkDir%References\10.0.17134.0\Windows.Foundation.FoundationContract\3.0.0.0\Windows.Foundation.FoundationContract.winmd" /reference "%WindowsSdkDir%References\10.0.17134.0\Windows.Foundation.UniversalApiContract\6.0.0.0\Windows.Foundation.UniversalApiContract.winmd" /reference "%WindowsSdkDir%\References\10.0.17134.0\Windows.Networking.Connectivity.WwanContract\2.0.0.0\Windows.Networking.Connectivity.WwanContract.winmd" Bookstore.idl
midl.exe
도구는 예제를 컴파일하고 Bookstore.winmd
메타데이터 파일을 생성합니다(기본적으로 .idl
파일의 이름이 사용됨).
팁
둘 이상의 IDL 파일을 사용하는 경우(이에 대한 자세한 내용은 런타임 클래스를 Midl 파일(.idl)팩터링 참조)한 다음 결과 .winmd
파일을 모두 루트 네임스페이스와 동일한 이름의 단일 파일에 병합합니다. 최종 .winmd
파일은 API 소비자가 참조하는 파일입니다.
이 경우 BookSkuBookstore 네임스페이스에서 유일한 런타임 클래스이므로 단계를 저장하고 네임스페이스의 .idl
파일 이름을 지정했습니다.
또한 where
명령을 사용하여 midl.exe
설치되는 위치를 확인할 수 있습니다.
where midl
다른 .idl
파일의 한 .idl
파일에 정의된 형식을 사용하려면 import
지시문을 사용합니다. 자세한 내용 및 코드 예제는 XAML 컨트롤을 참조하세요. C++/WinRT 속성바인딩합니다. 물론 기본 제공 또는 타사 구성 요소를 사용하는 경우 .idl
파일에 액세스할 수 없습니다. 예를 들어 즉시 모드 2D 그래픽 렌더링을 위해 Win2D Windows 런타임 API를 사용할 수 있습니다. 위의 명령은 /reference
스위치를 사용하여 Windows 런타임 메타데이터(.winmd
) 파일을 참조했습니다. 다음 예제에서는 해당 스위치를 다시 사용하여 Bookstore.winmd
있지만 Bookstore.idl
않은 시나리오를 상상합니다.
// MVVMApp.idl
namespace MVVMApp
{
runtimeclass ViewModel
{
ViewModel();
Bookstore.BookSku BookSku{ get; };
}
}
위의 예제의 소스 코드가 MVVMApp.idl
파일에 저장된 경우 아래 명령을 실행하여 Bookstore.winmd
참조할 수 있습니다.
midl /winrt /metadata_dir "%WindowsSdkDir%References\10.0.17134.0\windows.foundation.foundationcontract\3.0.0.0" /h "nul" /nomidl /reference "%WindowsSdkDir%References\10.0.17134.0\Windows.Foundation.FoundationContract\3.0.0.0\Windows.Foundation.FoundationContract.winmd" /reference "%WindowsSdkDir%References\10.0.17134.0\Windows.Foundation.UniversalApiContract\6.0.0.0\Windows.Foundation.UniversalApiContract.winmd" /reference "%WindowsSdkDir%\References\10.0.17134.0\Windows.Networking.Connectivity.WwanContract\2.0.0.0\Windows.Networking.Connectivity.WwanContract.winmd" /reference Bookstore.winmd MVVMApp.idl
네임스페이스
네임스페이스가 필요합니다. 네임스페이스 블록의 범위에 정의된 모든 형식의 이름 앞에 네임스페이스 이름을 접두사로 지정합니다. 네임스페이스에는 하위 네임스페이스 선언도 포함될 수 있습니다. 하위 네임스페이스 범위에 정의된 형식의 이름에는 포함된 모든 네임스페이스 이름의 접두사를 포함합니다.
아래 예제는 동일한 Windows.Foundation.Uri 클래스를 선언하는 두 가지 방법입니다(보듯이 마침표는 중첩된 네임스페이스 수준을 구분합니다).
namespace Windows.Foundation
{
runtimeclass Uri : IStringable
{
...
}
}
namespace Windows
{
namespace Foundation
{
runtimeclass Uri : IStringable
{
...
}
}
}
다음은 네임스페이스와 해당 형식을 중첩된 방식으로 선언하는 것이 합법적임을 보여주는 또 다른 예입니다.
namespace RootNs.SubNs1
{
runtimeclass MySubNs1Class
{
void DoWork();
}
namespace SubNs2
{
runtimeclass MySubNs2Class
{
void DoWork();
}
}
}
그러나 이전 네임스페이스를 닫고 다음과 같이 새 네임스페이스를 여는 것이 더 일반적입니다.
namespace RootNs.SubNs1
{
runtimeclass MySubNs1Class
{
void DoWork();
}
}
namespace RootNs.SubNs1.SubNs2
{
runtimeclass MySubNs2Class
{
void DoWork();
}
}
형식
MIDL 3.0에는 값 형식과 참조 형식이라는 두 가지 종류의 데이터 형식이 있습니다. 값 형식의 변수에는 해당 데이터가 직접 포함됩니다. 참조 형식의 변수는 해당 데이터에 대한 참조를 저장합니다(이러한 변수는
두 참조 형식 변수가 동일한 개체를 참조할 수 있습니다. 따라서 한 변수에 대한 작업은 다른 변수에서 참조하는 개체에 영향을 줍니다. 값 형식을 사용하면 변수마다 고유한 데이터 복사본이 있으며 한 변수에 대한 작업이 다른 변수에 영향을 줄 수 없습니다.
MIDL 3.0의 값 형식은 단순 형식, 열거형 형식, 구조체 형식 및 nullable 형식으로 더 구분됩니다.
MIDL 3.0의 참조 형식은 클래스 형식, 인터페이스 형식 및 대리자 형식으로 더 구분됩니다.
MIDL 3.0의 형식 시스템에 대한 개요는 다음과 같습니다. 이전 버전의 MIDL과 달리 이러한 형식에는 별칭을 사용할 수 없습니다.
범주 | 묘사 | |
---|---|---|
값 형식 | 단순 형식 | 부호 있는 정수: Int16, Int32, Int64 |
부호 없는 정수: UInt8, UInt16, UInt32, UInt64 | ||
유니코드 문자: Char(UTF-16LE, 16비트 유니코드 코드 단위를 나타낸다) | ||
유니코드 문자열: 문자열 | ||
IEEE 부동 소수점: 단일, Double | ||
부울: 부울 | ||
128비트 UUID: Guid | ||
열거형 형식 | E {...} |
|
구조체 형식 | 구조체 S {...} |
|
Nullable 형식 | null 값이 있는 다른 모든 값 형식의 확장 | |
참조 형식 | 클래스 형식 | 다른 모든 형식의 Ultimate 기본 클래스: Object |
runtimeclass C {...} |
||
인터페이스 형식 | 사용자 정의 형식의 양식 인터페이스 I {...} | |
대리자 형식 | returnType |
7개의 정수 계열 형식은 8비트 부호 없는 데이터를 지원합니다. 부호 있거나 서명되지 않은 형식의 16비트, 32비트 및 64비트 값
단일 및
MIDL 3.0의 부울 형식은 부울 값을 나타냅니다. true
또는 false
.
MIDL 3.0의 문자 및 문자열에는 유니코드 문자가 포함됩니다. Char 형식은 UTF-16LE 코드 단위를 나타냅니다. 및 문자열 형식은 UTF-16LE 코드 단위의 시퀀스를 나타냅니다.
다음 표에서는 MIDL 3.0의 숫자 형식을 요약합니다.
범주 | 비트 | 형 | 범위/정밀도 |
---|---|---|---|
부가 정수 | 16 | int16 |
–32,768...32,767 |
32 | int32 |
–2,147,483,648...2,147,483,647 | |
64 | int64 |
–9,223,372,036,854,775,808...9,223,372,036,854,775,807 | |
부호 없는 정수 | 8 | UInt8 |
0...255 |
16 | UInt16 |
0...65,535 | |
32 | UInt32 |
0...4,294,967,295 | |
64 | UInt64 |
0...18,446,744,073,709,551,615 | |
부동 소수점 | 32 | 단일 |
1.5 × 10-45 3.4 × 1038, 7 자리 정밀도 |
64 | Double | 5.0 × 10-324 ~ 1.7 × 10308, 15자리 정밀도 |
MIDL 3.0 원본 파일은 형식 정의를 사용하여 새 형식을 만듭니다. 형식 정의는 새 형식의 이름과 멤버를 지정합니다. 이러한 MIDL 3.0 형식 범주는 사용자가 정의할 수 있습니다.
- 특성 유형,
- 구조체 형식,
- 인터페이스 형식,
- runtimeclass 형식,
- 대리자 형식 및
- 열거형 형식입니다.
특성 형식은 다른 형식 정의에 적용할 수 있는 Windows 런타임 특성을 정의합니다. 특성은 특성이 적용되는 형식에 대한 메타데이터를 제공합니다.
구조체 형식은 데이터 멤버(필드)를 포함하는 Windows 런타임 구조를 정의합니다. 구조체는 값 형식이며 힙 할당이 필요하지 않습니다. 구조체 형식의 데이터 멤버는 값 형식 또는 nullable 형식이어야 합니다. 구조체 형식은 상속을 지원하지 않습니다.
인터페이스 형식은 명명된 함수 멤버 집합인 Windows 런타임 인터페이스를 정의합니다. 인터페이스는 인터페이스의 구현이 하나 이상의 지정된 추가(필수) 인터페이스를 구현해야 한다고 지정할 수 있습니다. 모든 인터페이스 형식은 Windows 런타임 IInspectable 인터페이스에서 직접 파생됩니다.
런타임 클래스 형식은 Windows 런타임 클래스(런타임 클래스)를 정의합니다. 런타임 클래스에는 속성, 메서드 및 이벤트일 수 있는 멤버가 포함됩니다.
대리자 형식은 특정 매개 변수 목록 및 반환 형식이 있는 메서드에 대한 참조를 나타내는 Windows 런타임 대리자를 정의합니다. 대리자를 사용하면 메서드를 매개 변수로 전달할 수 있는 엔터티로 처리할 수 있습니다. 대리자는 다른 언어에서 찾은 함수 포인터의 개념과 유사합니다. 함수 포인터와 달리 대리자는 개체 지향적이며 형식이 안전합니다.
열거형 형식은 명명된 상수가 있는 고유 형식입니다. 모든 열거형 형식에는 암시적 기본 형식이 있습니다. Int32
MIDL 3.0은 세 가지 추가 형식 범주를 지원합니다.
- 1차원 배열 형식,
- nullable 값 형식 및
- Object 형식입니다.
1차원 배열을 사용하려면 1차원 배열을 선언할 필요가 없습니다. 대신 배열 형식은 대괄호가 있는 형식 이름을 따라 생성됩니다. 예를 들어 Int32[]Int321차원 배열입니다.
마찬가지로 nullable 값 형식도 사용할 수 있기 전에 정의할 필요가 없습니다. Null을 허용하지 않는 각 값 형식 null
값을 보유할 수 있는 형식입니다. 또한 IReference<T>참조하세요.
마지막으로 MIDL 3.0은 Windows 런타임 IInspectable 인터페이스에 매핑되는 Object 형식을 지원합니다. 인터페이스 및 런타임 클래스 참조 형식은 개념적으로 Object 형식에서 파생됩니다. 대리자 그렇지 않습니다.
열거형 값의 식
MIDL 3.0에서는 열거형 형식의 명명된 상수 값 정의에
식은 new
있습니다. 피연산자의 예로는 리터럴, 필드, 지역 변수 및 식이 있습니다.
식에 여러 연산자가 포함된 경우 연산자의 우선 순위 개별 연산자가 계산되는 순서를 제어합니다. 예를 들어 * 연산자의 우선 순위가 + 연산자보다 높기 때문에 x + y * z 식은 x + (y * z)로 평가됩니다. 논리 작업은 비트 연산보다 우선 순위가 낮습니다.
다음 표에서는 MIDL 3.0 연산자를 요약하여 연산자 범주를 우선 순위에서 가장 낮은 순서로 나열합니다. 동일한 범주의 연산자는 동일한 우선 순위를 갖습니다.
범주 | 식 | 묘사 |
---|---|---|
본래의 | x++ | 증분 후 |
x-- | 감소 후 | |
단항 | +x | 신원 |
-x | 부정 | |
!x | 논리적 부정 | |
~x | 비트 부정 | |
++x | 사전 증가 | |
--x | 감소 전 | |
곱셈 | x * y | 곱셈 |
x / y | 나눗셈 | |
x % y | 나머지 | |
첨가물 | x + y | 더하기, 문자열 연결, 대리자 조합 |
x – y | 빼기, 대리자 제거 | |
교대 | x << y | 왼쪽으로 이동 |
x >> y | 오른쪽으로 이동 | |
비트 AND | x & y | 정수 비트 AND |
비트 XOR | x ^ y | 정수 비트 XOR |
비트 OR | x | y | 정수 비트 OR |
논리 AND | x && y | 부울 논리 AND |
논리적 OR | x || y | 부울 논리 OR |
클래스
클래스(또는 런타임 클래스)는 MIDL 3.0 형식의 가장 기본적인 요소입니다. 클래스는 단일 단위의 메서드, 속성 및 이벤트 집계에 대한 정의입니다. 클래스는
클래스 정의를 사용하여 새 클래스 형식을 정의합니다. 클래스 정의는 runtimeclass
키워드, 클래스 이름, 기본 클래스(지정된 경우) 및 클래스에서 구현하는 인터페이스를 지정하는 헤더로 시작합니다. 머리글 뒤에 클래스 본문이 있으며 구분 기호 { 및 }사이에 작성된 멤버 선언 목록으로 구성됩니다.
다음은 Area이라는 간단한 클래스의 정의입니다.
runtimeclass Area
{
Area(Int32 width, Int32 height);
Int32 Height;
Int32 Width;
static Int32 NumberOfAreas { get; };
}
기본적으로 런타임 클래스는 봉인되고 파생은 허용되지 않습니다. 기본 클래스참조하세요.
XAML을 뷰 모델에 바인딩하려면 뷰 모델 런타임 클래스를 MIDL에 정의해야 합니다. XAML 컨트롤을 참조하세요. 자세한 내용은 C++/WinRT 속성 바인딩합니다.
static
키워드를 사용하여 런타임 클래스 정의를 접두사로 지정하여 클래스가 인스턴스를 지원하지 않으며 결과적으로 정적 멤버만 포함해야 한다고 선언할 수 있습니다. 비정적 멤버를 클래스에 추가하면 컴파일 오류가 발생합니다.
static runtimeclass Area
{
static Int32 NumberOfAreas { get; };
}
정적 클래스는 빈 클래스와 다릅니다. 빈 클래스
런타임 클래스 정의 앞에 partial
키워드를 추가하여 클래스 정의가 불완전함을 나타낼 수 있습니다. 컴파일러에서 발생하는 모든 부분 클래스 정의는 단일 런타임 클래스로 결합됩니다. 이 기능은 주로 일부 부분 클래스가 기계 생성되는 XAML 제작 시나리오를 위한 것입니다.
수식어 | 의미 |
---|---|
정적인 | 클래스에는 인스턴스가 없습니다. 따라서 정적 멤버만 허용됩니다. |
부분적인 | 클래스 정의가 불완전합니다. |
고급 한정자는 컴퍼지션 및 활성화 참조하세요.
멤버 액세스 한정자
MIDL 3.0은 Windows 런타임 형식의 공용 표면을 설명하기 위한 정의 언어이므로 멤버의 공용 접근성을 선언하기 위한 명시적 구문이 필요하지 않습니다. 모든 멤버는 암시적으로 공용입니다. 따라서 MIDL 3.0은 (효과적으로 중복된) public
키워드를 요구하거나 허용하지 않습니다.
기본 클래스
클래스 정의는 콜론과 기본 클래스의 이름을 사용하여 클래스 이름 및 형식 매개 변수를 따라 기본 클래스를 지정할 수 있습니다. 기본 클래스 사양을 생략하는 것은 Object 형식에서 파생되는 것과 같습니다(즉, IInspectable).
메모
뷰 모델 클래스(실제로 애플리케이션에서 정의하는 런타임 클래스)는 기본 클래스에서 파생할 필요가 없습니다.
기본 클래스에서 파생되는 애플리케이션에서 정의하는 모든 런타임 클래스를 구성 가능한 클래스라고 합니다. 그리고 구성 가능한 클래스에 대한 제약 조건이 있습니다. 애플리케이션이 Visual Studio 및 Microsoft Store에서 제출 유효성을 검사하는 데 사용하는 Windows 앱 인증 키트 테스트를 통과하려면(따라서 애플리케이션이 Microsoft Store에 성공적으로 수집되려면) 구성 가능한 클래스는 궁극적으로 Windows 기본 클래스에서 파생되어야 합니다. 즉, 상속 계층 구조의 루트에 있는 클래스는 Windows.* 네임스페이스에서 시작되는 형식이어야 합니다.
다음 예제에서
unsealed runtimeclass Area : Windows.UI.Xaml.DependencyObject
{
Area(Int32 width, Int32 height);
Int32 Height;
Int32 Width;
}
runtimeclass Volume : Area
{
Volume(Int32 width, Int32 height, Int32 depth);
Int32 Depth;
}
메모
여기서 영역 및 볼륨 동일한 소스 파일에 정의됩니다. 장단점의 설명은 런타임 클래스를 Midl 파일(.idl)팩터링하는 방법을 참조하세요.
클래스는 기본 클래스의 멤버를 상속합니다. 상속은 기본 클래스의 생성자를 제외하고 클래스에 기본 클래스의 모든 멤버를 암시적으로 포함한다는 것을 의미합니다. 파생 클래스는 상속된 멤버에 새 멤버를 추가할 수 있지만 상속된 멤버의 정의를 제거할 수는 없습니다.
이전 예제에서 VolumeAreaHeight 및 Width 속성을 상속합니다. 따라서 모든 Volume 인스턴스에는 Height, Width및 Depth세 가지 속성이 포함됩니다.
일반적으로 형식 확인 규칙은 참조할 때 형식 이름을 정규화해야 합니다. 예외는 형식이 현재 형식과 동일한 네임스페이스에 정의된 경우입니다. 위의 예제는 영역 및 볼륨 모두 동일한 네임스페이스에 있는 경우 기록된 대로 작동합니다.
구현된 인터페이스
클래스 정의는 클래스가 구현하는 인터페이스 목록을 지정할 수도 있습니다. 인터페이스를 (선택 사항) 기본 클래스 다음에 쉼표로 구분된 인터페이스 목록으로 지정합니다.
아래 예제에서 Area 클래스는 IStringable 인터페이스를 구현합니다. Volume 클래스는 IStringable 가상 IEquatable 인터페이스를 모두 구현합니다.
unsealed runtimeclass Area : Windows.Foundation.IStringable
{
Area(Int32 width, Int32 height);
Int32 Height;
Int32 Width;
}
runtimeclass Volume : Area, Windows.Foundation.IStringable, IEquatable
{
Volume(Int32 width, Int32 height, Int32 depth);
Int32 Depth;
}
MIDL에서는 클래스에서 인터페이스의 멤버를 선언하지 않습니다. 물론 실제 구현에서 선언하고 정의해야 합니다.
회원
클래스의 멤버는 정적 멤버 또는인스턴스 멤버를
이 표에서는 클래스에 포함할 수 있는 멤버의 종류를 보여 줍니다.
멤버 종류 | 묘사 |
---|---|
생성자 | 클래스의 인스턴스를 초기화하거나 클래스 자체를 초기화하는 데 필요한 작업 |
속성 | 클래스 인스턴스 또는 클래스 자체의 명명된 속성 읽기 및 쓰기와 관련된 작업 |
방법 | 클래스의 인스턴스 또는 클래스 자체에서 수행할 수 있는 계산 및 작업 |
이벤트 | 클래스의 인스턴스에서 발생할 수 있는 알림 |
생성자
MIDL 3.0은 인스턴스 생성자 선언을 지원합니다. 인스턴스 생성자 클래스의 인스턴스를 초기화하는 데 필요한 작업을 구현하는 메서드입니다. 생성자가 정적이지 않을 수 있습니다.
생성자는 인스턴스 메서드처럼 선언되고(반환 형식은 없음), 포함하는 클래스와 동일한 이름으로 선언됩니다.
인스턴스 생성자를 오버로드할 수 있습니다. 예를 들어 아래
runtimeclass Test
{
Test();
Test(Int32 x);
Test(Double x, Double y);
}
매개 변수 목록의 구문에 대한 자세한 내용은 아래의 메서드 참조하세요.
인스턴스 속성, 메서드 및 이벤트가 상속됩니다. 인스턴스 생성자는 상속되지 않으며(한 가지 예외를 제외하고) 클래스에는 클래스에 실제로 선언된 생성자 이외의 인스턴스 생성자가 없습니다. 클래스에 대해 제공된 인스턴스 생성자가 없는 경우 클래스를 직접 인스턴스화할 수 없습니다. 이러한 클래스의 경우 일반적으로 클래스의 인스턴스를 반환하는 팩터리 메서드가 다른 곳에 있습니다.
예외는 봉인되지 않은 클래스입니다. 봉인되지 않은 클래스에는 하나 이상의 보호된 생성자가 있을 수 있습니다.
속성
속성 개념적으로 필드(예: C# 필드 또는 MIDL 3.0 구조체의 필드)와 비슷합니다. 속성과 필드는 모두 이름과 연결된 형식의 멤버입니다. 그러나 필드와 달리 속성은 스토리지 위치를 나타내지 않습니다. 대신 속성에는 속성을 읽거나 쓸 때 실행할 함수를 지정하는
선언이 구분 기호 {와 }사이에 작성된 get
키워드 및/또는 set
키워드로 끝나고 세미콜론으로 끝나는 것을 제외하고 속성은 구조체 필드처럼 선언됩니다.
get
키워드와 set
키워드가 모두 있는 속성은 읽기/쓰기 속성.
get
키워드만 있는 속성은 읽기 전용 속성. Windows 런타임은 쓰기 전용 속성을 지원하지 않습니다.
예를 들어 이전에 본 Area클래스에는 Height 및 Width라는 두 개의 읽기-쓰기 속성이 포함되어 있습니다.
unsealed runtimeclass Area
{
Int32 Height { get; set; };
Int32 Width; // get and set are implied if both are omitted.
}
Width 선언은 중괄호와 get
및 set
키워드를 생략합니다. 생략은 속성이 읽기/쓰기이며, get
및 set
키워드(get
및 set
)를 순서대로 제공하는 것과 의미상 동일함을 의미합니다.
또한 get
키워드만 지정하여 속성이 읽기 전용임을 나타낼 수 있습니다.
// Read-only instance property returning mutable collection.
Windows.Foundation.Collections.IVector<Windows.UI.Color> Colors { get; };
Windows 런타임은 쓰기 전용 속성을 지원하지 않습니다. 그러나 set
키워드만 지정하여 기존 읽기 전용 속성을 읽기-쓰기 속성으로 수정할 수 있습니다. 이 버전의 영역 예로 들어 하세요.
unsealed runtimeclass Area
{
...
Color SurfaceColor { get; };
}
이후에 SurfaceColor 속성을 읽기/쓰기로 만들고 Area 이전 정의와 이진 호환성을 유지할 필요가 없는 경우(예: Area 클래스는 매번 다시 컴파일하는 애플리케이션의 형식임) 다음과 같이 기존 SurfaceColor 선언에 set
키워드를 추가할 수 있습니다.
unsealed runtimeclass Area
{
...
Color SurfaceColor { get; set; };
}
반면에 이진 안정성이 필요한
이 경우 다음과 같이 클래스의 끝에 있는 속성의 추가 정의에 속성 set
키워드를 추가합니다.
unsealed runtimeclass Area
{
...
Color SurfaceColor { get; };
...
Color SurfaceColor { set; };
}
컴파일러는 쓰기 전용 속성에 대한 오류를 생성합니다. 하지만 여기서는 그런 일이 일어나고 있지 않습니다. 위의 속성 선언이 읽기 전용이므로 set 키워드를 추가해도 쓰기 전용 속성이 아니라 읽기/쓰기 속성이 선언됩니다.
속성의 Windows 런타임 구현은 인터페이스에서 하나 또는 두 개의 접근자 메서드입니다. 속성 선언에서 get 및 set 키워드의 순서는 백업 인터페이스에서 get 및 set 접근자 메서드의 순서를 결정합니다.
get
접근자가 속성 형식의 반환 값인 속성 getter를 사용하는 매개 변수 없는 메서드에 해당합니다.
set
접근자가 속성 setter라는 값반환 형식이 없는 단일 매개 변수가 있는 메서드에 해당합니다.
따라서 이러한 두 선언은 서로 다른 이진 인터페이스를 생성합니다.
Color SurfaceColor { get; set; };
Color SurfaceColor { set; get; };
정적 및 인스턴스 속성
메서드와 마찬가지로 MIDL 3.0은 인스턴스 속성과 정적 속성을 모두 지원합니다. 정적 속성은 접두사로 static
한정자를 사용하여 선언되고 인스턴스 속성은 접두사 없이 선언됩니다.
방법
메서드에는 메서드에 전달된 값 또는 변수 참조를 나타내는 매개 변수목록이 있습니다. 메서드에는 메서드에서 계산하고 반환하는 값의 형식을 지정하는 반환 형식있습니다. 메서드의 반환 형식은 값을 반환하지 않는 경우 void
.
// Instance method with no return value.
void AddData(String data);
// Instance method *with* a return value.
Int32 GetDataSize();
// Instance method accepting/returning a runtime class.
// Notice that you don't say "&" nor "*" for reference types.
BasicClass MergeWith(BasicClass other);
// Asynchronous instance methods.
Windows.Foundation.IAsyncAction UpdateAsync();
Windows.Foundation.IAsyncOperation<Boolean> TrySaveAsync();
// Instance method that returns a value through a parameter.
Boolean TryParseInt16(String input, out Int16 value);
// Instance method that receives a reference to a value type.
Double CalculateArea(ref const Windows.Foundation.Rect value);
// Instance method accepting or returning a conformant array.
void SetBytes(UInt8[] bytes);
UInt8[] GetBytes();
// instance method that writes to a caller-provided conformant array
void ReadBytes(ref UInt8[] bytes);
메서드의 서명 메서드가 선언된 클래스에서 고유해야 합니다. 메서드의 서명은 메서드의 이름, 해당 매개 변수의 형식 및/또는 해당 매개 변수의 수로 구성됩니다. 메서드의 서명에는 반환 형식이 포함되지 않습니다.
메서드 표시 유형 한정자
메서드 메서드가 파생 클래스에 있을 때 두 가지 선택적 표시 유형 한정자 중 하나가 있을 수 있습니다.
재정의 가능한 한정자는 이 메서드가 서브클래스에 속하는 메서드(이름과 서명이 같은)에 의해 재정의될 수 있음을 나타냅니다.
보호된 한정자는 이후에 파생된 클래스의 멤버만 이 메서드에 액세스할 수 있다고 명시합니다.
메서드 오버로드
메서드
runtimeclass Test
{
static void F();
static void F(Double x);
static void F(Double x, Double y);
}
메모
이름이 같은 모든 메서드는
매개 변수
매개 변수 메서드에 값 또는 변수 참조를 전달하는 데 사용됩니다.
매개 변수 형식과 이름을 가진 슬롯과 선택적으로 일부 한정자 키워드를 설명합니다.
메서드의 매개 변수는 메서드가 호출될 때 지정된 특정 인수 해당 값을 가져옵니다. 호출자와 호출자 간에 인수가 전달되는 방식은 매개 변수의 형식에 따라 달라집니다. 기본적으로 모든 매개 변수는입력 매개 변수를
중요하다
CLR(공용 언어 런타임)에는 이 섹션에 설명된 것과 비슷한 개념과 한정자 키워드가 있습니다. 그러나 실제로는 관련이 없으며 이러한 한정자의 효과는 Windows 런타임의 디자인 및 작동과 관련이 있습니다.
값 형식은입력 매개 변수를 암시적으로
runtimeclass Test
{
static void Divide(Int32 x, Int32 y, out Int32 result, out Int32 remainder);
}
특수한 성능 최적화로, 일반적으로 값으로 전체 복사본으로 전달되는 구조체 형식(및 다른 형식 없음)은 변경할 수 없는 구조체에 대한 포인터로 전달할 수 있습니다. 이는 구조체 매개 변수를 입력 매개 변수로 표시하지만 구조체의 전체 복사본을 전달하는 대신 마샬러가 구조체의 스토리지에 포인터를 전달하도록 지시하는
runtimeclass Test
{
static Boolean IsIdentity(ref const Windows.Foundation.Numerics.Matrix4x4 m);
}
참조 형식은 암시적으로 입력 매개 변수이기도 합니다. 즉, 호출자가 개체를 할당하고 참조를 인수로 전달해야 합니다. 그러나 인수는 개체에 대한 참조이므로 호출자가 호출한 후 호출자가 해당 개체를 수정하는 것을 관찰합니다. 또는 out
키워드를 사용하여 참조 형식을 출력 매개 변수로 만들 수 있습니다. 이 경우 역할이 반전됩니다. 호출 수신자는 개체를 할당하고 호출자에게 다시 반환하는 호출자입니다. 다시 ref
키워드는 일반적으로 참조 형식에서 사용할 수 없습니다(아래 예외 참조).
runtimeclass Test
{
static void CreateObjectWithConfig(Config config, out MyClass newObject);
}
다음 표에서는 값 매개 변수 및 참조 매개 변수에 대한 마샬링 키워드의 동작을 요약합니다.
행동 | 할당자 | 키워드 | 형식 | 발언 |
---|---|---|---|---|
입력 매개 변수 | 방문객 | (없음) | 모든 형식 | 기본 동작 |
ref const |
구조체만 | 성능 최적화 | ||
출력 매개 변수 | 수신자 | out |
모든 형식 |
Windows 런타임은 매개 변수로서의 동작이 다소 다른 배열 형식을 지원합니다.
배열 순차적으로 저장되고 인덱스를 통해 액세스되는 여러 변수를 포함하는 데이터 구조입니다. 배열의
MIDL 3.0은 1차원 배열선언을 지원합니다.
배열 매개 변수 참조 형식이며 모든 참조 형식과 마찬가지로 기본적으로 입력 매개 변수입니다. 이 경우 호출자는 해당 요소를 읽을 수 있지만 수정할 수 없는 배열을 호출 수신자에게 할당합니다(읽기 전용). 이를 전달 배열 패턴이라고 합니다. 또는 매개 변수에 ref
키워드를 추가하여 채우기 배열 패턴을 사용할 수 있습니다. 이 설정에서 배열은 여전히 호출자에 의해 할당되지만 개념적으로 호출 수신자가 배열 요소의 값을 채운다는 점에서 출력 매개 변수입니다. 마지막으로, 마지막 패턴은 호출자가 호출자에게 반환되기 전에 인수를 할당하고 초기화하는
runtimeclass Test
{
// Pass array pattern: read-only array from caller to callee
void PassArray(Int32[] values);
// Fill array pattern: caller allocates array for callee to fill
void FillArray(ref Int32[] values);
// Receive array pattern: callee allocates and fill an array returned to caller
void ReceiveArray(out Int32[] values);
}
다음 표에는 배열 및 해당 요소의 동작이 요약되어 있습니다.
배열 패턴 | 키워드 | 할당자 | 호출 수신자별 요소 액세스 |
---|---|---|---|
"배열 전달" | (없음) | 방문객 | 읽기 전용 |
"배열 채우기" | ref |
방문객 | 쓰기 전용 |
"배열 수신" | out |
수신자 | 읽기-쓰기 |
C++/WinRT에서 C 스타일 배열 매개 변수(준수 배열이라고도 함)를 사용하는 방법에 대한 자세한 내용은 배열 매개 변수참조하세요.
정적 및 인스턴스 메서드
접두사로 static
한정자를 사용하여 선언된 메서드는 정적 메서드. 정적 메서드는 특정 인스턴스에 액세스할 수 없으므로 클래스의 다른 정적 멤버에만 직접 액세스할 수 있습니다.
다음 Entity 클래스에는 정적 멤버와 인스턴스 멤버가 모두 있습니다.
runtimeclass Entity
{
Int32 SerialNo { get; };
static Int32 GetNextSerialNo();
static void SetNextSerialNo(Int32 value);
}
각 엔터티 인스턴스에는 고유한 일련 번호(및 여기에 표시되지 않는 다른 정보)가 포함되어 있습니다. 내부적으로 Entity 생성자(인스턴스 메서드와 같음)는 사용 가능한 다음 일련 번호로 새 인스턴스를 초기화합니다.
SerialNo 속성은 속성 get 메서드를 호출하는 인스턴스의 일련 번호에 대한 액세스를 제공합니다.
재정의 가능하고 보호된 메서드
Windows 런타임 형식의 모든 메서드는 사실상 가상입니다. 가상 메서드를 호출할 때 호출이 수행되는 인스턴스의
메서드는 파생 클래스에서 재정의된 overridable
한정자가 포함된 경우 파생 클래스에서 메서드를 재정의할 수 있습니다. 파생 클래스가 실제로 재정의 가능한 기본 클래스 메서드를 재정의하는지 여부는 구현에 의해 결정됩니다. 메타데이터에 없습니다. 파생 클래스가 기본 클래스에서 메서드를 다시 선언하는 경우 재정의하지 않고 파생 클래스 메서드와 함께 있는 새 메서드를 선언합니다.
인스턴스 메서드 선언에 protected
한정자가 포함된 경우 메서드는 파생 클래스에만 표시됩니다.
이벤트
이벤트 선언은 클래스가 이벤트 원본임을 지정하는 멤버입니다. 이러한 이벤트 원본은 대리자(특정 서명이 있는 메서드)를 구현하는 받는 사람에게 알림을 제공합니다.
event
키워드를 사용하여 이벤트를 선언한 다음, 대리자 형식 이름(필수 메서드 시그니처를 설명함) 뒤에 이벤트 이름이 잇습니다. 다음은 플랫폼에서 기존 대리자 형식을 사용하는 예제 이벤트입니다.
runtimeclass Area
{
...
event Windows.UI.Xaml.WindowSizeChangedEventHandler SizeChanged;
...
}
이벤트 선언은 암시적으로 클래스에 두 가지 메서드를 추가합니다. 메서드를 추가합니다. 이 메서드는 클라이언트가 소스에 이벤트 처리기를 추가하기 위해 호출하고 클라이언트가 이전에 추가한 이벤트 처리기를 제거하기 위해 호출하는 메서드를 제거합니다. 다음은 더 많은 예입니다.
// Instance event with no meaningful payload.
event Windows.Foundation.TypedEventHandler<BasicClass, Object> Changed;
// Instance event with event parameters.
event Windows.Foundation.TypedEventHandler<BasicClass, BasicClassSaveCompletedEventArgs> SaveCompleted;
// Static event with no meaningful payload.
static event Windows.Foundation.EventHandler<Object> ResetOccurred;
// Static event with event parameters.
static event Windows.Foundation.EventHandler<BasicClassDeviceAddedEventArgs> DeviceAdded;
규칙에 따라 두 매개 변수는 항상 Windows 런타임 이벤트 처리기에 전달됩니다. 보낸 사람의 ID와 이벤트 인수 개체입니다. 발신자는 이벤트를 발생시킨 개체이거나 정적 이벤트의 경우 null입니다. 이벤트에 의미 있는 페이로드가 없는 경우 이벤트 인수는 값이 null인 Object.
대리자
대리자 형식은 특정 매개 변수 목록과 반환 형식이 있는 메서드를 지정합니다. 이벤트의 단일 인스턴스는 대리자 형식의 인스턴스에 대한 참조 수를 포함할 수 있습니다. 이 선언은 런타임 클래스 외부에 있고 delegate
키워드 앞에 접두사를 추가한다는 점을 제외하고 일반 멤버 메서드의 선언과 비슷합니다.
대리자를 사용하면 메서드를 변수에 할당하고 매개 변수로 전달할 수 있는 엔터티로 처리할 수 있습니다. 대리자는 다른 언어에서 찾은 함수 포인터의 개념과 유사합니다. 그러나 함수 포인터와 달리 대리자는 개체 지향적이며 형식이 안전합니다.
플랫폼에서 WindowSizeChangedEventHandler 대리자 형식을 사용하지 않으려면 자체 대리자 형식을 정의할 수 있습니다.
delegate void SizeChangedHandler(Object sender, Windows.UI.Core.WindowSizeChangedEventArgs args);
SizeChangedHandler 대리자 형식의 인스턴스는 두 개의 인수(Object및 WindowSizeChangedEventArgs)를 사용하고 void를 반환하는 모든 메서드를 참조할 수 있습니다.
대리자의 흥미롭고 유용한 속성은 참조하는 메서드의 클래스를 모르거나 신경 쓰지 않는다는 것입니다. 참조된 메서드에 대리자와 동일한 매개 변수 및 반환 형식이 있다는 것이 중요합니다.
필요에 따라 [uuid(...)]
사용하여 대리자 선언의 특성을 지정할 수 있습니다.
또한 HRESULT반환하는
구조체
구조체 데이터 멤버(필드)를 포함할 수 있는 데이터 구조체입니다. 그러나 클래스와 달리 구조체는 값 형식입니다.
구조체는 값 의미 체계가 있는 작은 데이터 구조에 특히 유용합니다. 복소수 또는 좌표계의 점이 구조체의 좋은 예입니다. 작은 데이터 구조체에 대한 클래스가 아닌 구조체를 사용하면 애플리케이션이 수행하는 메모리 할당 수에 큰 차이를 만들 수 있습니다.
예제를 사용하여 클래스와 구조체를 대조해 보겠습니다. 다음은 클래스첫 번째 Point 버전입니다.
runtimeclass Point
{
Point(Int32 x, Int32 y);
Int32 x;
Int32 y;
}
이 C# 프로그램은 Point100개 인스턴스의 배열을 만들고 초기화합니다. Point 클래스로 구현되면 배열 개체 자체에 대해 하나씩 101개의 개별 개체가 인스턴스화됩니다. 100개의 Point 요소 각각에 대해 하나씩
class Test
{
static Test()
{
Point[] points = new Point[100];
for (Int32 i = 0; i < 100; ++i) points[i] = new Point(i, i);
}
}
더 성능이 좋은 대안은 Point 클래스 대신 구조체로 만드는 것입니다.
struct Point
{
Int32 x;
Int32 y;
};
이제 배열 개체 자체인 하나의 개체만 인스턴스화됩니다. Point 요소는 배열 내부에 줄에 저장됩니다. 프로세서 캐시가 강력한 효과를 발휘하는 데 사용할 수 있는 메모리 정렬입니다.
구조체 변경은 이진 호환성이 손상되는 변경입니다. 따라서 Windows 자체의 일부로 구현된 구조체는 도입된 후에는 변경되지 않습니다.
인터페이스
인터페이스 클래스에서 구현할 수 있는 계약을 정의합니다. 인터페이스는 클래스와 마찬가지로 메서드, 속성 및 이벤트를 포함할 수 있습니다.
클래스와 달리 인터페이스는 정의하는 멤버의 구현을 제공하지 않습니다. 인터페이스를 구현하는 모든 클래스에서 제공해야 하는 멤버만 지정합니다.
인터페이스는 다른 인터페이스를 구현하기 위해 인터페이스를 구현하는 클래스를 필요할 수 있습니다. 다음 예제에서 IComboBox
interface IControl
{
void Paint();
}
interface ITextBox requires IControl
{
void SetText(String text);
}
interface IListBox requires IControl
{
void SetItems(String[] items);
}
interface IComboBox requires ITextBox, IListBox
{
...
}
클래스는 0개 이상의 인터페이스를 구현할 수 있습니다. 다음 예제에서 EditBox 클래스는 IControl 및 IDataBound모두 구현합니다.
interface IDataBound
{
void Bind(Binder b);
}
runtimeclass EditBox : IControl, IDataBound
{
}
Windows 플랫폼의 Windows 런타임 형식의 경우 이러한 형식을 사용하는 개발자가 인터페이스를 구현해야 하는 경우 인터페이스가 정의됩니다. 인터페이스를 정의하는 또 다른 사용 사례는 여러 런타임 클래스가 인터페이스를 구현하고 해당 런타임 클래스를 사용하는 개발자가 해당 공통 인터페이스를 통해 일반적으로(따라서 다형적으로) 다양한 유형의 개체에 액세스하는 경우입니다.
메모
MIDL 3.0에서 requires
키워드를 사용하는 방법을 두 번 생각해 보세요. 특히 버전 관리가 고려될 때 지저분한 디자인으로 이어질 수 있습니다.
열거형
열거형 형식(또는 열거형 형식 또는 열거형)은 명명된 상수 집합이 있는 고유 값 형식입니다. 다음 예제에서는 세 가지 상수 값이 있는 Color 열거형 형식을 정의하고 사용합니다. 빨강, 녹색및 Blue.
enum Color
{
Red,
Green,
Blue, // Trailing comma is optional, but recommended to make future changes easier.
};
각 열거형 형식에는 열거형 형식의 기본 형식 해당하는 정수 계열 형식이 있습니다. 열거형의 기본 형식은 Int32
Windows 런타임은 두 종류의 열거형인 일반 열거형과 플래그 열거형을 지원합니다. 일반 종류의 열거형은 배타적 값 집합을 나타냅니다. 플래그 종류 중 하나가 부울 값 집합을 나타내는 동안 플래그 열거형에 비트 연산자를 사용하도록 설정하기 위해 MIDL 3.0 컴파일러는 C++ 연산자 오버로드를 생성합니다.
플래그 열거형에는 [flags]
특성이 적용됩니다. 이 경우 열거형의 기본 형식은 UInt32
[flags]
enum SetOfBooleanValues
{
None = 0x00000000,
Value1 = 0x00000001,
Value2 = 0x00000002,
Value3 = 0x00000004,
};
열거형 형식의 스토리지 형식 및 가능한 값 범위는 기본 형식에 따라 결정됩니다. 열거형 형식이 사용할 수 있는 값 집합은 선언된 열거형 멤버에 의해 제한되지 않습니다.
다음 예제에서는 기본 형식의 Int32사용하여 Alignment열거형 형식을 정의합니다.
enum Alignment
{
Left = -1,
Center = 0,
Right = 1
};
C 및 C++의 경우와 마찬가지로 MIDL 3.0 열거형에는 위와 같이 멤버의 값을 지정하는 상수 식이 포함될 수 있습니다. 각 열거형 멤버의 상수 값은 열거형의 기본 형식 범위에 있어야 합니다. 열거형 멤버 선언에서 값을 명시적으로 지정하지 않으면 멤버에 값 0(열거형 형식의 첫 번째 멤버인 경우) 또는 텍스트 앞에 오는 열거형 멤버의 값과 1이 부여됩니다.
다음 예제에서는 기본 형식의 UInt32사용하여 Permissions열거형 형식을 정의합니다.
[flags]
enum Permissions
{
None = 0x0000,
Camera = 0x0001,
Microphone = 0x0002
};
특성
MIDL 3.0 소스 코드의 형식, 멤버 및 기타 엔터티는 동작의 특정 측면을 제어하는 한정자를 지원합니다. 예를 들어 메서드의 접근성은 protected
액세스 한정자를 사용하여 제어됩니다. MIDL 3.0은 사용자 정의 형식의 선언적 정보를 프로그램 엔터티에 연결하고 메타데이터에서 런타임에 검색할 수 있도록 이 기능을 일반화합니다.
프로그램에서는
다음 예제에서는 연결된 설명서에 대한 링크를 제공하기 위해 프로그램 엔터티에 배치할 수 있는 HelpAttribute 특성을 정의합니다. 보듯이 특성은 기본적으로 구조체 형식이므로 생성자가 없고 데이터 멤버만 포함합니다.
[attributeusage(target_runtimeclass, target_event, target_method, target_property)]
attribute HelpAttribute
{
String ClassUri;
String MemberTopic;
}
연결된 선언 바로 앞에 대괄호 안에 인수와 함께 해당 이름을 지정하여 특성을 적용할 수 있습니다. 특성의 이름이 특성으로 끝나는 경우 특성이 참조될 때 이름의 해당 부분을 생략할 수 있습니다. 예를 들어 HelpAttribute 특성을 다음과 같이 사용할 수 있습니다.
[Help("https://docs.contoso.com/.../BookSku", "BookSku class")]
runtimeclass BookSku : Windows.UI.Xaml.Data.INotifyPropertyChanged
{
[Help("https://docs.contoso.com/.../BookSku_Title", "Title method")]
String Title;
}
특성 다음에 있는 범위 블록을 사용하여 여러 선언에 동일한 특성을 적용할 수 있습니다. 즉, 특성 바로 뒤에 특성이 적용되는 선언을 둘러싼 중괄호가 잇습니다.
runtimeclass Widget
{
[Help("https://docs.contoso.com/.../Widget", "Widget members")]
{
void Display(String text);
void Print();
Single Rate;
}
}
Windows 자체의 일부로 구현되는 특성은 일반적으로 Windows.Foundation 네임스페이스에 있습니다.
첫 번째 예제와 같이 특성 정의에 [attributeusage(<target>)]
특성을 사용합니다. 유효한 대상 값은 target_all
, target_delegate
, target_enum
, target_event
, target_field
, target_interface
, target_method
, target_parameter
, target_property
, target_runtimeclass
및 target_struct
. 쉼표로 구분된 여러 대상을 괄호 안에 포함할 수 있습니다.
특성에 적용할 수 있는 다른 특성은 [allowmultiple]
[attributename("<name>")]
.
매개 변수가 있는 형식
아래 예제에서는 오류 MIDL2025 생성합니다. [msg]구문 오류 [context]: > 예상 또는 ">>"근처.
Windows.Foundation.IAsyncOperation<Windows.Foundation.Collections.IVector<String>> RetrieveCollectionAsync();
대신 템플릿 닫는 문자 쌍이 오른쪽 시프트 연산자로 잘못 해석되지 않도록 두 >
문자 사이에 공백을 삽입합니다.
Windows.Foundation.IAsyncOperation<Windows.Foundation.Collections.IVector<String> > RetrieveCollectionAsync();
아래 예제에서는 오류 MIDL2025 생성합니다. [msg]구문 오류 [context]: 예상 > 또는 "["근처. 이는 배열을 매개 변수가 있는 인터페이스에 대한 매개 변수 형식 인수로 사용하는 것이 잘못되었기 때문입니다.
Windows.Foundation.IAsyncOperation<Int32[]> RetrieveArrayAsync();
솔루션은 배열을 비동기적으로반환을 참조하세요.