Conjuntos de API do Windows

Importante

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

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

O objetivo de um conjunto de APIs é fornecer uma separação arquitetônica da DLL do host na qual uma determinada API Win32 é implementada e o contrato funcional ao qual a API pertence. O desacoplamento que os conjuntos de APIs fornecem entre a implementação e os contratos oferece 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 toda a amplitude da API Win32 seja suportada em PCs, apenas um subconjunto da API Win32 está disponível em outros dispositivos Windows, como HoloLens, Xbox e outros dispositivos. O nome do conjunto de APIs fornece um mecanismo de consulta para detectar claramente se uma API está disponível em um determinado dispositivo.

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

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

Conjuntos de API e dlls são a mesma coisa?

Não—um nome de conjunto de API é um alias virtual para um arquivo físico.dll. É uma técnica de ocultação de implementação, onde 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 (divididos, consolidados, renomeados e assim por diante) em diferentes versões e edições do Windows. E seus aplicativos ainda se vinculam e ainda são roteados para o código correto em tempo de execução.

Então, por que os conjuntos de API têm .dll em seus nomes? O motivo é a forma como o carregador de DLL é implementado. O carregador é a parte do sistema operacional que carrega DLLs e/ou resolve referências a DLLs. E no front-end, o carregador requer que qualquer string passada para LoadLibrary seja encerrada com ".dll". Mas depois desse front-end, o carregador pode remover esse sufixo e consultar o banco de dados do conjunto de APIs com a cadeia de caracteres resultante.

LoadLibrary (e delay load) é bem-sucedido com um nome de conjunto de API (com o ".dll" nele), mas não há necessariamente um arquivo real com esse nome em qualquer lugar do PC.

Vinculando bibliotecas guarda-chuva

Para facilitar a restrição de seu código a APIs Win32 com suporte no sistema operacional principal, fornecemos uma série de bibliotecas guarda-chuva. Por exemplo, uma biblioteca guarda-chuva chamada OneCore.lib fornece as exportações para o subconjunto de APIs Win32 que são comuns a todos os dispositivos Windows.

Para obter mais detalhes, consulte Bibliotecas guarda-chuva do Windows.

Nomes de contrato do conjunto de APIs

Os conjuntos de API são identificados por um nome de contrato forte que segue essas convenções padrão reconhecidas pelo carregador de bibliotecas.

  • O nome deve começar com a cadeia de caracteres api- ou ext-.
    • Os nomes que começam com api- representam APIs que têm a garantia de existir em todas as versões do Windows.
    • Os nomes que começam com ext- representam APIs que podem não existir em todas as versões do Windows.
  • O nome deve terminar com a sequência l<n-n-n<,< onde n>>> consiste em dígitos decimais.
  • O corpo do nome pode ser caracteres alfanuméricos ou traços (-).
  • O nome diferencia maiúsculas de minúsculas.

Aqui estão alguns exemplos de nomes de contrato de conjunto de API:

  • api-ms-win-core-ums-l1-1-0
  • ext-ms-win-com-ole32-l1-1-5
  • ext-ms-win-ntuser-window-l1-1-0
  • ext-ms-win-ntuser-window-l1-1-1

Você pode usar um nome de conjunto de API no contexto de uma operação de carregador, como LoadLibrary ou P/Invoke , em vez de um nome de módulo DLL para garantir uma rota correta para a implementação, não importa onde a API esteja realmente implementada no dispositivo atual. No entanto, ao fazer isso, você deve acrescentar a cadeia de caracteres .dll no final do nome do contrato. Este é um requisito do carregador para funcionar corretamente, e não é considerado realmente uma parte do nome do contrato. Embora os nomes de contrato pareçam semelhantes aos nomes de DLL nesse contexto, eles são fundamentalmente diferentes dos nomes de módulo de DLL e não se referem diretamente a um arquivo no disco.

Exceto para acrescentar a cadeia de caracteres .dll em operações de carregador, os nomes de contrato de conjunto de API devem ser considerados um identificador imutável que corresponde a uma versão específica do contrato.

Identificando conjuntos de APIs para APIs Win32

Para identificar se uma API Win32 específica pertence a um conjunto de APIs, examine 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:

Nesta seção