Conjuntos de API do Windows

Importante

As informações neste tópico se aplicam a todas as versões do Windows 10 e posteriores. Nos referiremos a essas versões aqui como "Windows", indicando quaisquer exceções quando necessário.

Todas as versões do Windows compartilham uma base comum de componentes do sistema operacional (SO) chamada de SO principal (em alguns contextos, essa base comum também é conhecida como OneCore). Nos principais componentes do sistema operacional, as APIs do Win32 são organizadas em grupos funcionais chamados conjuntos de APIs.

A finalidade de um conjunto de API é fornecer uma separação arquitetônica entre a DLL de host na qual uma determinada API Win32 é implementada e o contrato funcional ao qual a API pertence. A separação que os conjuntos de APIs fornecem entre a implementação e os contratos leva a muitas vantagens de engenharia para os desenvolvedores. Em particular, o uso de conjuntos de API em seu código pode melhorar a compatibilidade com dispositivos Windows.

Os conjuntos de API abordam especificamente os seguintes cenários:

  • Embora haja suporte para toda a amplitude da API Win32 em computadores, apenas um subconjunto da API Win32 está disponível em outros dispositivos Windows, como HoloLens, XBOX e outros dispositivos. Um nome de conjunto de APIs fornece uma referência estável para consulta, para que seu aplicativo possa verificar, em tempo de execução, se um recurso está disponível no dispositivo atual. A consulta em si é executada pela função IsApiSetImplemented .

  • Algumas implementações da API do Win32 existem em DLLs com nomes distintos em dispositivos Windows diferentes. Usar nomes de conjunto de API em vez de nomes de DLL ao detectar a disponibilidade da API e atrasar o carregamento de APIs fornece uma rota correta para a implementação, independentemente de onde a API seja realmente implementada.

Para mais detalhes, consulte Operação do carregador de conjunto de API e Detectar disponibilidade do conjunto de API.

Os conjuntos de API e as DLLs são a mesma coisa?

Não — um nome de conjunto de API identifica um contrato, não um arquivo. Em tempo de execução, o carregador resolve esse contrato por meio do esquema de conjunto de API no dispositivo atual e roteia a referência para a DLL que hospeda a implementação. É uma técnica de ocultação de implementação, em que você, como chamador, não precisa saber exatamente qual módulo está hospedando as informações.

A técnica permite que os módulos sejam refatorados (separados, consolidados, renomeados e assim por diante) em diferentes versões e edições do Windows. E seus aplicativos continuam vinculados e continuam sendo direcionados ao código correto em tempo de execução.

Então, por que os conjuntos de APIs têm .dll em seus nomes? O motivo é a forma como o carregador da DLL é implementado. O carregador é a parte do sistema operacional que carrega DLLs e/ou resolve referências a DLLs e identifica o que carregar por um nome de módulo escrito como os nomes de arquivo são escritos em uma tabela de importação. Os nomes dos conjuntos de APIs seguem a mesma convenção para que caibam no mesmo espaço.

O carregador reconhece um nome que começa com api- ou ext- roteia-o para o runtime do conjunto de API, uma extensão do carregador que resolve contratos por meio do esquema. A partir desse ponto, o nome é analisado pelas regras de nomenclatura do conjunto de API em vez de como um nome de arquivo, de modo que o .dll sufixo não faz parte do nome do contrato que está sendo resolvido.

Você pode passar o nome de um conjunto de APIs para LoadLibrary, ou usá-lo como um destino para carregamento atrasado. A operação é bem-sucedida quando o esquema no dispositivo atual mapeia esse contrato para um host utilizável; não há necessariamente um arquivo real com esse nome em qualquer lugar no computador. Se o contrato não estiver mapeado no dispositivo atual, uma chamada direta a LoadLibrary falhará. Uma referência carregada tardiamente se comporta de forma diferente: o processo continua sendo carregado, e a ausência só se torna aparente mais tarde, quando a API é chamada.

De qualquer forma, um link ou carga bem-sucedido não é, por si só, uma evidência de que uma implementação está presente. Para determinar isso, consulte Detectar disponibilidade do conjunto de API.

Vincular bibliotecas agregadoras

Para facilitar a restrição do código às APIs do Win32 com suporte no sistema operacional principal, fornecemos uma série de bibliotecas abrangentes. Uma biblioteca de guarda-chuvas permite vincular uma única biblioteca em vez de identificar a biblioteca de importação individual para cada API chamada.

Para obter mais detalhes e escolher a biblioteca umbrella que corresponde à sua plataforma de destino, consulte bibliotecas umbrella do Windows.

Nomes de contrato do conjunto de API

Os conjuntos de API são identificados por um nome de contrato que segue as convenções reconhecidas pelo carregador de biblioteca.

Todos os nomes de contrato compartilham estas convenções:

  • O nome começa com a sequência de caracteres api- ou com ext-.
  • O corpo do nome pode ser composto por caracteres alfanuméricos ou traços (-). Um til (~) aparece apenas como separador antes de um nome de grupo.
  • O nome não diferencia maiúsculas de minúsculas.

Duas formas de nome do contrato estão em uso e você pode encontrar uma delas.

Um nome de contrato versionado termina com a sequência l<n>->n<->n<, em que n é composto por dígitos decimais — por exemplo, ext-ms-win-core-samplefeature-l1-1-0. Os números à direita identificam uma versão específica do contrato e um nome nesse formulário deve ser considerado um identificador imutável para essa versão.

Um alias do contrato não tem versão, por exemplo, api-win-core-samplefeature. Ele identifica o contrato em si, em vez de uma versão dele. Quando um contrato organiza suas funcionalidades disponíveis individualmente em grupos nomeados, um grupo é referenciado anexando o nome do grupo ao alias do contrato, separado por um til: api-win-core-samplefeature~AdvancedOperations.

Os samplefeature nomes usados aqui são nomes ilustrativos para um componente de Windows fictício.

Os prefixos api- e ext-

O prefixo é uma convenção de nomenclatura. Foi originalmente destinado a distinguir contratos que estão presentes em todas as edições qualificadas (api-) de contratos que poderiam estar ausentes (ext-). Essa distinção não foi aplicada consistentemente, e a função de um contrato pode mudar ao longo do tempo sem que o contrato seja renomeado.

O carregador não atribui nenhum significado ao prefixo; resolve os nomes api- e ext- pelas mesmas regras. Não deduza a disponibilidade com base no prefixo. Em vez disso, consulte isso — veja Verificar a disponibilidade do conjunto de APIs.

Uso de um nome de contrato

Dois tipos diferentes de operação levam um nome de contrato.

As operações do carregador, como LoadLibrary ou P/Invoke, assumem o nome do contrato no mesmo local em que um nome de módulo DLL aparece normalmente. Um acréscimo .dll é convencional nesse contexto, mas não é exigido pela resolução de nomes do conjunto de API e não faz parte do nome do contrato. Use um nome de contrato em vez de um nome de módulo de DLL físico para garantir uma rota correta para a implementação, independentemente de onde a API seja realmente implementada no dispositivo atual. Não é necessário haver um arquivo com esse nome de contrato no disco.

Os exemplos de consulta de disponibilidade omitem convencionalmente o sufixo .dll e usam o formulário que corresponde à maneira como a API é tratada:

Superfície da API Formulário de consulta Example
Grupo nomeado <contract>~<group> api-win-core-samplefeature~AdvancedOperations
Grupo padrão Apelido do contrato, sem ~Default api-win-core-samplefeature
Contrato versionado Nome completo do contrato versionado ext-ms-win-core-samplefeature-l1-1-0

Um nome de grupo não pode ser combinado a um nome de contrato versionado.

Identificar conjuntos de APIs para APIs do Win32

Para identificar se uma API do Win32 específica pertence a um conjunto de APIs, analise a tabela de requisitos na documentação de referência da API. Se a API pertencer a um conjunto de APIs, a tabela de requisitos no artigo listará o nome do conjunto de APIs e a versão do Windows na qual a API foi introduzida pela primeira vez no conjunto de APIs. Para obter exemplos de APIs que pertencem a um conjunto de APIs, consulte estes artigos:

Se o cabeçalho da API fornecer uma Is<APIName>Present função auxiliar, prefira esse auxiliar ao testar a disponibilidade. Ele já contém o nome correto para o conjunto de API ou grupo que carrega a API. Para obter mais informações, consulte Detectar disponibilidade do conjunto de API.

Nesta seção