Share via


定義済み属性 (MIDL 3.0)

コンパイラで合成されたインターフェイスの名前とインターフェイス識別子 (IID) を制御できる定義済みのカスタム属性がいくつかあります。 これらの属性を使用すると、クラスのバージョン管理とバイナリ API を細かいレベルで制御できます。

コンポーネント開発者やライブラリ作成者の場合は、これらの属性を使用して、コンポーネントが1つのバージョンから次のバージョンに対してバイナリ安定であることを確認する必要があります。

アプリケーション開発者は、通常、これらの属性を使用する必要はありません。型をリビジョン管理した後にアプリケーションを再コンパイルするためです。

[allowforweb]属性

属性の allowforweb 使用法と用途の詳細については、「 Allowforwebattribute クラス」を参照してください。

[constructor_name]属性

属性は constructor_name 、コンストラクターのメンバーを含むファクトリインターフェイスの名前と IID を指定します。 ファクトリインターフェイスの詳細については、「 からインターフェイス 」を参照してください。

Note

ファクトリインターフェイスは、既定以外のコンストラクターを持つシールクラス、または既定のコンストラクターまたは既定以外のコンストラクターを持つシールされていないクラスにのみ適用できます。

次の例では、protected Block コンストラクターが iblockfactory インターフェイスに配置され、そのインターフェイスには指定された IID があります。

[constructor_name("Windows.UI.Xaml.Documents.IBlockFactory", 07110532-4f59-4f3b-9ce5-25784c430507)]
...
unsealed runtimeclass Block : Windows.UI.Xaml.Documents.TextElement
{
    ...
    protected Block();
    ...
}

その結果、クラスの説明がインターフェイスを参照しない場合でも、クラスを実装するために必要な場合は、必要に応じて MIDL 3.0 コンパイラによってインターフェイスが合成され、追加されます。

[contentproperty]属性

contentpropertyContentPropertyAttributeクラスを表す属性です。 次に例を示します。

// BgLabelControl.idl
namespace BgLabelControlApp
{
    [contentproperty("Content")]
    runtimeclass BgLabelControl : Windows.UI.Xaml.Controls.Control
    {
        BgLabelControl();
        static Windows.UI.Xaml.DependencyProperty LabelProperty{ get; };
        String Label;
        static Windows.UI.Xaml.DependencyProperty ContentProperty{ get; };
        IInspectable Content;
    }
}

[contract]属性

独自の api では属性を使用 contract しないでください。組み込みの Windows api の場合にのみ意味があります。

属性は contract 、Windows 10 API コントラクトの名前とバージョンを指定します (「拡張 sdk を使用したプログラミング」を参照してください)。これは、属性付きの型およびメンバーが最初に Windows に導入されたものです (したがって、Windows の一部として提供されていない api では意味がありません)。 属性はフォーム [contract(ContractName, ContractVersion)] を受け取り、適用される項目の前に表示されます。

[default]属性

既定のインターフェイスを指定しない場合、MIDL 3.0 コンパイラは最初のインスタンスインターフェイスを選択します。 この選択をオーバーライドするには、インターフェイスの前に既定のインターフェイスとして使用する属性を挿入 default します。

// Declaring an external interface as the default
runtimeclass C : [default]I { ... }

// Declaring a specific exclusiveto interface as the default.
// This is very unusual.
runtimeclass C
{
    ...

    [default][interface_name(...)]
    {
        ...
    }
}

[default_interface]属性

default_interface属性は、既定のインターフェイスを強制的に生成するために使用されますが、それ以外の場合は生成されません。 次の例では、 StateTriggerBaseは既定のインターフェイスを必要としません (パブリックの非静的メンバーがないため)。したがって、1つの (名前付きIStateTriggerBase) を生成する属性のみが存在 default_interface します。

[default_interface]
unsealed runtimeclass StateTriggerBase
{
    protected void SetActive(Boolean IsActive);
};

[default_overload]属性

Note

コンストラクターでは、この属性はサポートされていません。 コンストラクターをアリティによってオーバーロードできない場合は、このセクションの最後のコードスニペットに示されている Createfromuricreatefromuri の例など、オーバーロードされたファクトリメソッドを定義できます。

default_overloadWindows.foundation.metadata.defaultoverloadattributeクラスを表す属性です。これは、メソッドが既定のオーバーロードメソッドであることを示します。 このセクションでは、属性のの 理由 と使用ガイドライン [default_overload] について説明します。

Windows ランタイムメソッドは、アリティによって自由にオーバーロードできます。 つまり、同じ名前を持つ複数のメソッドを定義できます。ただし、それぞれに異なる数の引数を指定する必要があります。 使いやすさを向上させるために、新しいパラメーターを末尾に追加することをお勧めします。また、省略可能なパラメーターリスト関数の動作は、不足しているパラメーターに対して (シナリオ固有の) 自然な既定値を指定して、より長いパラメーターリスト関数を呼び出すことと同じになります。

runtimeclass Widget
{
    void Start();
    void Start(StartMode mode);
    void Start(StartMode mode, Widget parent);
}

上の例では、開始モードと親ウィジェットを指定するために、2つのパラメーターを使用して start を呼び出すことができます。 親ウィジェットを省略した場合、既定値は null になります。 また、モードを省略した場合は、シナリオ固有の既定のモードで開始されます。

次の例では、 Deviceinformation. CreateWatcher を使用します。

runtimeclass DeviceInformation
{
    static DeviceWatcher CreateWatcher();
    static DeviceWatcher CreateWatcher(DeviceClass deviceClass);
    static DeviceWatcher CreateWatcher(String aqsFilter);
    static DeviceWatcher CreateWatcher(String aqsFilter,
                                       IIterable<String> additionalProperties);
    static DeviceWatcher CreateWatcher(String aqsFilter,
                                       IIterable<String> additionalProperties,
                                       DeviceInformationKind kind);
}

この例では5つのオーバーロードがあり、そのほとんどは、新しいオーバーロードを前のオーバーロードの拡張として使用するための推奨パターンに従います。

同じ数のパラメーターを持つメソッドの複数のオーバーロードを使用する場合、コンパイラエラーが発生します。

DeviceInformation. CreateWatcher の1つのパラメーターのオーバーロードには、Windows で修飾することによって、既定のオーバーロードとして指定されたメソッドが1つだけ必要です。Windows.foundation.metadata.defaultoverloadattribute。

いくつかのプログラミング言語が動的に型指定される理由。 JavaScript と Python の2つの例を次に示します。 これらの言語では、オーバーロードを選択すると、その型ではなく、パラメーターの数のみが考慮されます。 これは、へ DeviceInformation.createWatcher(v); の JavaScript 呼び出しがあいまいであることを意味します。 vDeviceclassまたは 文字列に強制的に変換されますか。

あいまいさを解決するには、メソッドのいずれかに属性を適用 [default_overload] する必要があります。 しかし、どのような方法を選択するのでしょうか。

既定のオーバーロードを選択して、既定以外のオーバーロードの機能を他の方法で引き続き使用できるようにする必要があります。通常は、他のオーバーロードのいずれかによって使用できます。

Deviceinformation. CreateWatcherの例では、文字列オーバーロードIIterable <>を呼び出し、プロパティの空のリストを渡すことによって、文字列オーバーロードの機能を取得できます。 一方、deviceclass オーバーロードはdeviceclassにフィルター処理されたdevicewatcherを作成する唯一の方法です。

これにより、 Deviceclass メソッドが明確に優先されます。 そのため、そのオーバーロードに属性を適用 [default_overload] して、を指定します。

runtimeclass DeviceInformation
{
    static DeviceWatcher CreateWatcher();
    [default_overload]
    static DeviceWatcher CreateWatcher(DeviceClass deviceClass);
    static DeviceWatcher CreateWatcher(String aqsFilter);
    static DeviceWatcher CreateWatcher(String aqsFilter,
                                       IIterable<String> additionalProperties);
    static DeviceWatcher CreateWatcher(String aqsFilter,
                                       IIterable<String> additionalProperties,
                                       DeviceInformationKind kind);
}

競合するすべてのオーバーロードは、他のオーバーロードからは使用できない独自の機能を提供しているため、優先されない場合はどうすればよいでしょうか。

runtimeclass Widget
{
    static Widget Create(Uri source);
    static Widget Create(IInputStream source);
}

架空の ウィジェット オブジェクトは、 Uriから作成することも、入力ストリームから作成することもできます。 1つを既定のオーバーロードとしてマークすると、動的に型指定されたプログラミング言語は、他の言語にアクセスできなくなります。

この問題を解決するには、オーバーロードされないように、2つのバージョンに異なる名前を付けます。

runtimeclass Widget
{
    static Widget CreateFromUri(Uri source);
    static Widget CreateFromStream(IInputStream source);
}

これで、両方の作成パターンをすべての言語で使用できるようになりました。

メソッドのオーバーロード 」および「 クラスベースの射影」も参照してください。

[interface_name]属性

属性は interface_name 、クラスのインスタンスメンバーを格納するインターフェイスの名前と IID を指定します。 既定では、コンパイラは メソッドに使用するのと同じ一意の番号付けアルゴリズムを使用して、インターフェイス名を割り当てます。

interface_name の例では、runtimeclass に適用される属性に、インターフェイスに割り当てられていないクラスのすべてのインスタンスメンバーを含むインターフェイスの名前と IID が指定されています。 そのため、 LineheightLineStackingStrategyMargin、および textalignment は、 iblock インターフェイスのメンバーです。

ただし、水平方向のTextalignmentは、そのメンバーを含む属性により interface_nameIBlock2インターフェイスのメンバーです。

[interface_name("Windows.UI.Xaml.Documents.IBlock", 4bce0016-dd47-4350-8cb0-e171600ac896)]
...
unsealed runtimeclass Block : Windows.UI.Xaml.Documents.TextElement
{
    ...
    Double LineHeight;
    Windows.UI.Xaml.LineStackingStrategy LineStackingStrategy;
    Windows.UI.Xaml.Thickness Margin;
    Windows.UI.Xaml.TextAlignment TextAlignment;

    [interface_name("Windows.UI.Xaml.Documents.IBlock2", 5ec7bdf3-1333-4a92-8318-6caedc12ef89)]
    {
        Windows.UI.Xaml.TextAlignment HorizontalTextAlignment;
    }
    ...
}

属性を使用 interface_name して、インターフェイスを強制的に生成することもできます。 次の例では、 StateTriggerBaseIStateTriggerBaseを必要とせず、生成される属性のみが存在 interface_name します。

[interface_name("Windows.UI.Xaml.IStateTriggerBase", 48b20698-af06-466c-8052-93666dde0e49)]
unsealed runtimeclass StateTriggerBase
{
    protected void SetActive(Boolean IsActive);
};

その結果、クラスの説明がインターフェイスを参照しない場合でも、クラスを実装するために必要な場合は、必要に応じて MIDL 3.0 コンパイラによってインターフェイスが合成され、追加されます。

不要なを使用 default_interface すると、MIDL 3.0 は余分な のインターフェイスを生成し、それを既定値にします。

[method_name]属性

すべての Windows ランタイムインターフェイスには、同等のアプリケーションバイナリインターフェイス (ABI) インターフェイスがあります。 ABI インターフェイスでは、すべてのメンバーが一意の名前を持っている必要があります。 MIDL 3.0 には、メンバーが名前を持たない場合、または一意の名前を持たない場合の2つのケースがあります。

  • コンストラクター、および
  • 2つ以上のオーバーロードされたメソッド。

このような場合、MIDL 3.0 コンパイラは、必要に応じて一意のメンバー名を合成します。

既定では、コンパイラは、ABI インターフェイスの同等のメソッドに対して、 classname> 、 <classname> 2、 <classname> 3 などの名前 < のコンストラクターメソッドを割り当てます。 言い換えると、コンストラクターメソッド名が一意になるように、未使用の最小の整数の数字サフィックス (2 から増加) が追加されます。

同様に、オーバーロードされたメソッドの場合、一連のオーバーロードの最初のメソッド (構文的な順序) では、コンパイラは、同等の ABI インターフェイスメソッドに元のメソッド名を使用します。 それ以降のオーバーロードは、使用されていない最小の整数の数字サフィックス (2 から増加) を元の名前に追加することで一意になります。

たとえば、次の IDL は、 DoWorkの3つのオーバーロードと、 DoWork3という名前の別のメソッドの2つのオーバーロードを宣言しています。

void DoWork(Int32 x);
void DoWork3(Int32 x);
void DoWork(Int32 x, Int32 y);
void DoWork(Int32 x, Int32 y, Int32 z);
void DoWork3(Int32 x, Int32 y);

既定では、 DoWork3 という名前が既に取得されているため、コンパイラは、名前の DoWork の3つのオーバーロードを使用します。

  • DoWork
  • DoWork2
  • DoWork4

DoWork3DoWorkオーバーロードではありません。 既定では、コンパイラは名前の DoWork3 の2つのオーバーロードを使用します。

  • DoWork3
  • DoWork32

Vtable の順序では、関数は次のように表示されます。

  • DoWork
  • DoWork3
  • DoWork2
  • DoWork4
  • DoWork32

属性を使用して method_name 、コンパイラの既定の名前の割り当てをオーバーライドできます。

次の例では、ブロックの既定のコンストラクターメンバーにCreateInstanceという名前を使用するようにコンパイラに指示しています。

unsealed runtimeclass Block : Windows.UI.Xaml.Documents.TextElement
{
    ...
    [method_name("CreateInstance")] protected Block();
    ...
}

[static_name]属性

属性は static_name 、クラスの静的メンバーを含むインターフェイスの名前と IID を指定します。

次の例 static_name では、runtimeclass に適用される属性に、インターフェイスに割り当てられていないクラスのすべての静的メンバーを含むインターフェイスの名前と IID が指定されています。 そのため、 Line高さプロパティLineStackingStrategyPropertyMarginProperty、および Text プロパティ は、 iblockstatics インターフェイスのメンバーです。

ただし、水平方向のTextIBlockStatics2 プロパティは、そのメンバーを含む属性があるため static_name 、このインターフェイスのメンバーです。

[static_name("Windows.UI.Xaml.Documents.IBlockStatics", f86a8c34-8d18-4c53-aebd-91e610a5e010)]
...
unsealed runtimeclass Block : Windows.UI.Xaml.Documents.TextElement
{
    ...
    static Windows.UI.Xaml.DependencyProperty LineHeightProperty{ get; };
    static Windows.UI.Xaml.DependencyProperty LineStackingStrategyProperty{ get; };
    static Windows.UI.Xaml.DependencyProperty MarginProperty{ get; };
    static Windows.UI.Xaml.DependencyProperty TextAlignmentProperty{ get; };

    [static_name("Windows.UI.Xaml.Documents.IBlockStatics2", af01a4d6-03e3-4cee-9b02-2bfc308b27a9)]
    {
        static Windows.UI.Xaml.DependencyProperty HorizontalTextAlignmentProperty{ get; };
    }
    ...
}