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) 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 APIs é funcionar como uma separação arquitetônica da DLL do host em que uma determinada API do Win32 e o contrato funcional a que a API pertence são implementados. 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 à amplitude total da API do Win32 em computadores, apenas um subconjunto da API do Win32 está disponível para outros dispositivos Windows, como HoloLens, Xbox e outros dispositivos. O nome do conjunto de APIs fornece um mecanismo de consulta para detectar corretamente se uma API está disponível em um determinado dispositivo.
Algumas implementações da API do Win32 existem em DLLs com nomes distintos em dispositivos Windows diferentes. Usar nomes do conjunto de API em vez de nomes de DLL ao detectar a disponibilidade da API e atrasar o carregamento das APIs fornece um caminho para a implementação, independentemente de onde a API está realmente implementada.
Para mais detalhes, consulte Operação do carregador de conjunto de API e Detectar disponibilidade do conjunto de API.
Conjuntos de API e DLLs são a mesma coisa?
Não, um nome de conjunto de API é um alias virtual de um arquivo .dll
físico. É 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 ainda são vinculados e roteados para o código correto em runtime.
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, no front-end, o carregador exige que qualquer string passada para LoadLibrary termine 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 string resultante.
LoadLibrary (e atrasar carregamento) é bem-sucedido com um nome de conjunto de API (com ".dll" nele); mas não há necessariamente um arquivo real com esse nome em nenhum lugar do PC.
Vincular bibliotecas abrangentes
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. Por exemplo, uma biblioteca abrangente chamada OneCore.lib
fornece as exportações para o subconjunto de APIs do Win32 que são comuns a todos os dispositivos Windows.
Para mais detalhes, consulte Bibliotecas abrangentes do Windows.
Nomes de contrato do conjunto de API
Os conjuntos de API são identificados por um nome de contrato forte que segue essas convenções padrão reconhecidas pelo carregador da biblioteca.
- O nome deve começar com a cadeia de caracteres api- ou ext-.
- Os nomes que começam com api- representam APIs que existem em todas as versões do Windows que atendem aos requisitos de versão da API.
- 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 podem ser caracteres alfanuméricos ou traços (-).
- O nome diferencia maiúsculas de minúsculas.
Aqui estão alguns exemplos de nomes de contrato do conjunto de APIs:
- 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 o nome de um conjunto de APIs no contexto de uma operação do carregador, como LoadLibrary ou P/Invoke , em vez de um nome de módulo da DLL para garantir uma rota correta para a implementação, independente do lugar em que a API está realmente implementada no dispositivo atual. No entanto, ao fazer isso, você deve acrescentar a string de caracteres .dll no final do nome do contrato. Esse é um requisito do carregador para funcionar corretamente e não é considerado realmente uma parte do nome do contrato. Embora os nomes de contrato se pareçam com os 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 anexar a string .dll em operações de carregador, os nomes de contrato do conjunto de API devem ser considerados um identificador imutável que corresponde a uma versão específica do contrato.
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: