Since DLLs are essentially the same as EXEs, the choice of which to produce as part of the linking process is for clarity, since it is possible to export functions and data from either.
não é possível executar diretamente um DLL, uma vez que requer um EXE para o sistema operacional carregá-lo através de um ponto de entrada, daí a existência de utilitários como RUNDLL.EXE ou RUNDLL32.EXE que fornecem o ponto de entrada e o framework mínimo para DLLs que contêm funcionalidade suficiente para executar sem muito suporte.,
DLLs fornece um mecanismo para código compartilhado e dados, permitindo que um desenvolvedor de código compartilhado/dados para atualizar a funcionalidade sem exigir que os aplicativos sejam re-ligados ou re-compilados. Do ponto de vista do desenvolvimento de Aplicações, O Windows e o OS/2 podem ser considerados como uma coleção de DLLs que são atualizados, permitindo que aplicações para uma versão do SO para trabalhar em uma versão posterior, desde que o vendedor de SO tenha assegurado que as interfaces e funcionalidades são compatíveis.,
DLLs executam no espaço de memória do processo de chamada e com as mesmas permissões de acesso, o que significa que há pouca sobrecarga em seu uso, mas também que não há proteção para o EXE de chamada se o DLL tem qualquer tipo de bug.
Memory managementEdit
na API do Windows, os ficheiros DLL estão organizados em secções. Cada seção tem seu próprio conjunto de atributos, tais como ser escrita ou apenas para leitura, executável (para código) ou não-executável (para dados), e assim por diante.,
o código em um DLL é geralmente compartilhado entre todos os processos que usam o DLL; ou seja, eles ocupam um único lugar na memória física, e não ocupam espaço no arquivo da página. Windows não usa código independente de posição para seus DLLs; em vez disso, o código passa por realocação como ele é carregado, fixando endereços para todos os seus pontos de entrada em locais que são livres no espaço de memória do primeiro processo a carregar o DLL., Em versões mais antigas do Windows, em que todos os processos em execução ocupavam um único espaço de endereçamento comum, uma única cópia do Código DLL seria sempre suficiente para todos os processos. No entanto, em versões mais recentes do Windows que usam espaços de endereços separados para cada programa, só é possível usar a mesma cópia realocada do DLL em vários programas se cada programa tem os mesmos endereços virtuais livres para acomodar o código do DLL., Se alguns programas (ou sua combinação de DLLs já carregados) não têm esses endereços livres, então uma cópia física adicional do Código do DLL terá de ser criado, usando um conjunto diferente de pontos de entrada realocados. Se a memória física ocupada por uma seção de código deve ser recuperada, seu conteúdo é descartado, e mais tarde recarregado diretamente do arquivo DLL, conforme necessário.
em contraste com seções de código, as seções de dados de uma DLL são geralmente privadas; ou seja, cada processo usando a DLL tem sua própria cópia de todos os dados da DLL., Opcionalmente, as seções de dados podem ser compartilhadas, permitindo a comunicação entre processos através desta área de memória compartilhada. No entanto, como as restrições do Usuário não se aplicam ao uso de memória DLL compartilhada, isso cria um buraco de segurança, ou seja, um processo pode corromper os dados compartilhados, o que provavelmente fará com que todos os outros processos de compartilhamento se comportem de forma indesejável. Por exemplo, um processo em execução sob uma conta de hóspedes Pode, desta forma, corromper outro processo em execução sob uma conta privilegiada. Esta é uma razão importante para evitar o uso de seções compartilhadas em DLLs.,
Se uma DLL é comprimida por certos pacotes executáveis (por exemplo, UPX), todas as suas seções de código são marcadas como lidas e escritas, e não serão compartilhadas. As secções de código de leitura e escrita, tal como as secções de dados privadas, são privadas para cada processo. Assim, DLLs com seções de dados compartilhados não devem ser comprimidos se eles são destinados a ser usados simultaneamente por vários programas, uma vez que cada instância de programa teria que carregar sua própria cópia do DLL, resultando em aumento do consumo de memória.
Import librariesEdit
Like static libraries, import libraries for DLLs are noted by the .,lib extensão de ficheiro. Por exemplo, kernel32.dll, a biblioteca dinâmica primária para funções de base do Windows, como criação de arquivos e gerenciamento de memória, está ligada via kernel32.dado. A maneira usual de dizer a uma biblioteca de importação de uma biblioteca estática adequada é por tamanho: a biblioteca de importação é muito menor, pois só contém símbolos referentes ao DLL real, para ser processado no link-time. Ambos, no entanto, são arquivos Unix ar formato.
ligar-se a bibliotecas dinâmicas é normalmente tratado ligando-se a uma biblioteca de importação ao construir ou ligar-se para criar um ficheiro executável., O executável criado contém então uma tabela de endereços de importação (IAT) pela qual todas as chamadas de função DLL são referenciadas (cada função DLL referenciada contém sua própria entrada no IAT). No tempo de execução, o IAT é preenchido com endereços apropriados que apontam diretamente para uma função no DLL carregado separadamente.
em Cygwin / MSYS e MinGW, as bibliotecas de importação são convencionalmente dadas o sufixo .dll.a
, combinando tanto o sufixo Windows DLL como o sufixo Unix ar., O formato do ficheiro é semelhante, mas os símbolos utilizados para marcar as importações são diferentes (_head_foo_dll vs __importar_descritor_foo). Embora a sua ferramenta Binutils GNU possa gerar bibliotecas de importação e ligar a elas, é mais rápido ligar diretamente ao DLL. Uma ferramenta experimental no MinGW chamada genlib pode ser usada para gerar bibliotecas de importação com símbolos do estilo MSVC.
resolução de símbolos e bindingEdit
cada função exportada por um DLL é identificada por um ordinal numérico e opcionalmente um nome. Da mesma forma, funções podem ser importadas de um DLL por ordinal ou pelo nome., O ordinal representa a posição do ponteiro de endereço da função na tabela de endereços de exportação DLL. É comum as funções internas serem exportadas apenas por ordinal. Para a maioria das funções da API do Windows, apenas os nomes são preservados em diferentes versões do Windows; os ordinais estão sujeitos a alterações. Assim, não é possível importar de forma confiável as funções da API do Windows por seus ordinais.
importar funções por ordinal fornece apenas um desempenho ligeiramente melhor do que importá-las pelo nome: as tabelas de exportação de DLLs são ordenadas pelo nome, de modo que uma busca binária pode ser usada para encontrar uma função., O índice do nome encontrado é então usado para procurar o ordinal na tabela Ordinal de exportação. Em janelas de 16 bits, a tabela de nomes não foi ordenada, por isso a pesquisa de nomes por cima era muito mais perceptível.
também é possível vincular um executável a uma versão específica de uma DLL, ou seja, para resolver os endereços das funções importadas no tempo de compilação. Para as importações encadernadas, o linker poupa o timestamp e o checksum do DLL ao qual a importação está ligada. Em tempo de execução, O Windows verifica se a mesma versão da biblioteca está sendo usada, e se assim for, o Windows contorna o processamento das importações., Caso contrário, se a Biblioteca é diferente da que estava ligada, O Windows processa as importações de uma forma normal.
Obrigado executáveis carregar um pouco mais rápido se eles são executados no mesmo ambiente que eles foram compilados para, e exatamente o mesmo tempo, se eles são executados em um ambiente diferente, então não há nenhuma desvantagem para a ligação de importações. Por exemplo, todas as aplicações padrão do Windows estão ligadas aos DLLs do sistema de sua respectiva liberação do Windows. Uma boa oportunidade para vincular as importações de uma aplicação ao seu ambiente alvo é durante a instalação da aplicação., Isto mantém as bibliotecas ‘ligadas’ até a próxima atualização do sistema operacional. Ele faz, no entanto, alterar o checksum do executável, de modo que não é algo que pode ser feito com programas assinados, ou programas que são gerenciados por uma ferramenta de gerenciamento de configuração que usa checksums (como md5 checksums) para gerenciar versões de arquivos. Como versões mais recentes do Windows se afastaram de ter endereços fixos para cada biblioteca carregada (por razões de segurança), a oportunidade e o valor de vincular um executável está diminuindo.,
Explícito de tempo de execução linkingEdit
arquivos DLL pode ser carregada explicitamente em tempo de execução, um processo conhecido simplesmente como executar a vinculação dinâmica do tempo pela Microsoft, usando o LoadLibrary
(ou LoadLibraryEx
) função de API. A função APIGetProcAddress
é usada para procurar símbolos exportados pelo nome, eFreeLibrary
– para descarregar a DLL. Estas funções são análogas dlopen
dlsym
e dlclose
no padrão POSIX API.,
o procedimento para vinculação explícita de tempo de execução é o mesmo em qualquer linguagem que suporta ponteiros para funções, uma vez que depende da API do Windows em vez de construções de linguagem.
loadingEdit retardado
normalmente, uma aplicação que está ligada à biblioteca de importação de uma DLL não será iniciada se a DLL não puder ser encontrada, porque o Windows não irá executar a aplicação a menos que possa encontrar todas as DLLs que a aplicação possa necessitar. No entanto, uma aplicação pode ser ligada a uma biblioteca de importação para permitir o carregamento tardio da biblioteca dinâmica.,Neste caso, o sistema operacional não tentará encontrar ou carregar o DLL quando a aplicação começar; em vez disso, um stub é incluído na aplicação pelo linker que tentará encontrar e carregar o DLL através do LoadLibrary e GetProcAddress quando uma de suas funções for chamada. Se o DLL não puder ser encontrado ou carregado, ou a função chamada não existir, a aplicação irá gerar uma exceção, que pode ser capturada e tratada adequadamente. Se a aplicação não lidar com a exceção, ele será pego pelo sistema operacional, que irá terminar o programa com uma mensagem de erro.,
o mecanismo de carregamento de atraso também fornece ganchos de notificação, permitindo que a aplicação execute processamento adicional ou tratamento de erros quando a DLL é carregada e/ou qualquer função DLL é chamada.
Deixe uma resposta