Atributos predefinidos (MIDL 3.0)

Há vários atributos personalizados predefinidos que permitem controlar o nome e o identificador de interface (IID) para interfaces sintetizadas pelo compilador. Esses atributos permitem controlar o controle de versão e a API binária de sua classe em um nível refinado.

Se você for um desenvolvedor de componentes e/ou um autor de biblioteca, talvez queira usar esses atributos para garantir que seus componentes permaneçam binários estáveis de uma versão para outra.

Se você for um desenvolvedor de aplicativos, em geral, não precisará usar esses atributos porque você recompilará seu aplicativo após a revisão de seus tipos.

O [allowforweb] atributo

Para obter detalhes sobre o uso e a finalidade do allowforweb atributo, consulte a classe AllowForWebAttribute.

O [constructor_name] atributo

O constructor_name atributo especifica o nome e o IID da interface de fábrica que contém os membros do construtor. Consulte sintetizando interfaces para obter mais informações sobre interfaces de fábrica.

Observação

Uma interface de fábrica só é aplicável a uma classe selada com construtores não padrão ou a uma classe sem lacre com construtores padrão e/ou não padrão.

No exemplo a seguir, o construtor de bloco protegido é colocado na interface IBlockFactory e essa interface tem o IID especificado.

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

Como resultado, quando a descrição de sua classe não faz referência a uma interface, mas quando uma delas é necessária para implementar a classe, o compilador MIDL 3,0 sintetiza e adiciona interfaces, conforme necessário.

O [contentproperty] atributo

o contentproperty atributo representa a classe ContentPropertyAttribute . Veja um exemplo:

// 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;
    }
}

O [contract] atributo

não use o contract atributo em suas próprias apis; ele só tem significado para APIs de Windows internas.

o contract atributo especifica o nome e a versão do contrato de API Windows 10 (consulte programação com SDKs de extensão) em que o tipo e/ou membro atribuído primeiro foi introduzido no Windows (portanto, não é significativo para APIs não entregues como parte de Windows). O atributo assume o formulário [contract(ContractName, ContractVersion)] e aparece antes do item ao qual se aplica.

O [default] atributo

Se você não especificar uma interface padrão, o compilador MIDL 3,0 escolherá a primeira interface de instância. Para substituir essa seleção, insira o default atributo antes da interface que você deseja que seja a interface padrão.

// 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(...)]
    {
        ...
    }
}

O [default_interface] atributo

O default_interface atributo é usado para forçar a geração de uma interface padrão em que outra não seria gerada. No exemplo a seguir, StateTriggerBase não precisa de uma interface padrão (porque não tem nenhum membro público não estático), portanto, é apenas a presença do default_interface atributo que faz com que um (chamado IStateTriggerBase) seja gerado.

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

O [default_overload] atributo

Observação

Não há suporte para este atributo para construtores. Se você não puder sobrecarregar os construtores por arity, poderá definir métodos de fábrica sobrecarregados, como os exemplos de CreateFromUri e CreateFromStream mostrados no último trecho de código nesta seção.

O default_overload atributo representa a classe defaultoverloadattribute , que indica que um método é o método de sobrecarga padrão. Esta seção orienta você pelo motivo para o atributo e as diretrizes de uso para o [default_overload] .

você pode sobrecarregar Windows Runtime métodos livremente por arity. Ou seja, é possível definir vários métodos com o mesmo nome, desde que cada um aceite um número diferente de argumentos. Para fins de usabilidade, recomendamos que você adicione novos parâmetros ao final e que o comportamento da função de lista de parâmetros mais curto seja equivalente a chamar a função de lista de parâmetros mais longos com padrões naturais (específicos do cenário) para os parâmetros ausentes.

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

No exemplo acima, Start pode ser chamado com dois parâmetros para especificar um modo de início e um widget pai. Se você omitir o widget pai, o padrão será NULL. E se você omitir o modo, ele será iniciado em algum modo padrão específico do cenário.

Usamos DeviceInformation. createinspetor neste exemplo a seguir.

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);
}

Nesse exemplo, há cinco sobrecargas, e a maioria deles segue o padrão recomendado de ter cada sobrecarga nova ser uma extensão da sobrecarga anterior.

Se você decidir ter várias sobrecargas de um método com o mesmo número de parâmetros, obterá um erro do compilador:

As sobrecargas de um parâmetro de DeviceInformation. createassister devem ter exatamente um método especificado como a sobrecarga padrão decorando-a com Windows. Foundation. Metadata. defaultoverloadattribute.

O motivo é que algumas linguagens de programação são digitadas dinamicamente. JavaScript e Python são dois exemplos. Para esses idiomas, a seleção da sobrecarga considera apenas o número de parâmetros e não seus tipos. Isso significa que uma chamada JavaScript para DeviceInformation.createWatcher(v); é ambígua — deve ser forçada a um DeviceClassou a uma cadeia de caracteres?

Para resolver a ambiguidade, você precisa aplicar o [default_overload] atributo a um dos métodos. Mas como escolher qual delas?

Você deve escolher a sobrecarga padrão para que a funcionalidade das sobrecargas não padrão ainda esteja disponível por outros meios, geralmente por uma das outras sobrecargas.

No exemplo DeviceInformation. Createassister , a funcionalidade da sobrecarga da cadeia de caracteres pode ser obtida chamando a cadeiade caracteres, a sobrecarga da cadeia de caracteres > IIterable < e passando uma lista vazia de propriedades. Por outro lado, a sobrecarga DeviceClass é a única maneira de criar um DeviceWatcher que é filtrado para um DeviceClass.

Isso torna o método DeviceClass o vencedor claro. Portanto, você indica que aplicando o [default_overload] atributo a essa sobrecarga.

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);
}

E se não houver vencedor, pois todas as sobrecargas conflitantes fornecem funcionalidade exclusiva não disponível a partir de outras sobrecargas?

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

Nosso objeto de widget hipotético pode ser criado a partir de um URIou criado a partir de um fluxo de entrada. Se marcarmos uma como a sobrecarga padrão, as linguagens de programação de tipo dinâmico perderão completamente o acesso ao outro.

Para resolver esse problema, dê a duas versões nomes diferentes para que elas não sejam sobrecarregadas.

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

Agora os dois padrões de criação estão disponíveis para todos os idiomas.

Consulte também a sobrecarga de método e a projeção baseada em classe.

O [interface_name] atributo

O interface_name atributo especifica o nome e o IID da interface que contém os membros da instância da classe. Por padrão, o compilador atribui nomes de interface usando o mesmo algoritmo de numeração exclusivo que ele usa para métodos.

No exemplo a seguir, o interface_name atributo aplicado ao runtimeclass especifica o nome e o IID da interface que contém todos os membros de instância da classe que não são atribuídos de outra forma a uma interface. Portanto, LineHeight, LineStackingStrategy, Margine TextAlignment são membros da interface IBlock .

No entanto, HorizontalTextAlignment é um membro da interface IBlock2 , devido ao interface_name atributo que abrange esse membro.

[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;
    }
    ...
}

Você também pode usar o interface_name atributo para forçar a geração de uma interface. No exemplo a seguir, StateTriggerBase não tem necessidade de IStateTriggerBase, e é apenas a presença do interface_name atributo que faz com que ele seja gerado.

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

Como resultado, quando a descrição de sua classe não faz referência a uma interface, mas quando uma delas é necessária para implementar a classe, o compilador MIDL 3,0 sintetiza e adiciona interfaces, conforme necessário.

Se você usar o desnecessariamente, o default_interface MIDL 3,0 gerará uma interface vazia extra e tornará o padrão.

O [method_name] atributo

cada interface de Windows Runtime tem uma interface ABI (interface binária de aplicativo) equivalente. A interface ABI requer que todos os membros tenham nomes exclusivos. Há dois casos no MIDL 3,0, em que os membros não têm um nome ou não têm um nome exclusivo.

  • construtores e
  • dois ou mais métodos sobrecarregados.

Nesses casos, o compilador MIDL 3,0 sintetiza um nome de membro exclusivo, conforme necessário.

Por padrão, o compilador atribui métodos de Construtor aos nomes <ClassName> , <ClassName> 2, <ClassName> 3 e assim por diante para os métodos equivalentes na interface Abi. Em outras palavras, o menor sufixo de numeral inteiro não utilizado (aumentando de 2) é adicionado para tornar exclusivo o nome do método de construtor.

Da mesma forma, para métodos sobrecarregados, para o primeiro método em uma série de sobrecargas (em ordem lexical), o compilador usa o nome do método original para o método de interface ABI equivalente. Sobrecargas subsequentes são tornadas exclusivas adicionando ao nome original o menor sufixo de numeral inteiro não utilizado (aumentando de 2).

Por exemplo, a IDL a seguir declara três sobrecargas de DoWorke duas sobrecargas de um método diferente chamado DoWork3.

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);

Por padrão (como o nome DoWork3 já está em uso), o compilador fornece a três sobrecargas de DoWork os nomes

  • DoWork
  • DoWork2
  • DoWork4.

DoWork3não é uma sobrecarga de DoWork . Por padrão, o compilador fornece a duas sobrecargas de DoWork3 os nomes

  • DoWork3
  • DoWork32.

Em ordem vtable, as funções serão exibidas como

  • DoWork
  • DoWork3
  • DoWork2
  • DoWork4
  • DoWork32

Você pode substituir a atribuição de nome padrão do compilador usando o method_name atributo.

Neste próximo exemplo, instruimos o compilador a usar o nome CreateInstance para o membro do construtor padrão Bloquear.

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

O [static_name] atributo

O static_name atributo especifica o nome e a IID da interface que contém membros estáticos da classe .

Neste próximo exemplo, static_name o atributo aplicado à runtimeclass especifica o nome e o IID da interface que contém todos os membros estáticos da classe que não são atribuídos a uma interface de outra forma. Portanto, LineHeightProperty, LineStackingStrategyProperty, MarginProperty e TextAlignmentProperty são membros da interface IBlockStatics .

No entanto, HorizontalTextAlignmentProperty é um membro da interface IBlockStatics2 , static_name devido ao atributo que abrange esse membro.

[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; };
    }
    ...
}