O que são bibliotecas dinâmicas?
A maior parte da funcionalidade de uma aplicação está implementada em bibliotecas de código executável. Quando um aplicativo é ligado a uma biblioteca usando um linker estático, o código que o aplicativo usa é copiado para o arquivo executável gerado. Um linker estático coleta o código fonte compilado, conhecido como código objeto, e o código da biblioteca em um arquivo executável que é carregado na memória em sua totalidade em tempo de execução. O tipo de biblioteca que se torna parte de um arquivo executável de um aplicativo é conhecido como biblioteca estática. Bibliotecas estáticas são coleções ou arquivos de arquivos objetos.
Quando um aplicativo é iniciado, o código do aplicativo – que inclui o código das bibliotecas estáticas com as quais ele foi ligado – é carregado no espaço de endereços do aplicativo. Ligando muitas bibliotecas estáticas em uma aplicação produz grandes arquivos executáveis da aplicação. A Figura 1 mostra o uso de memória de um aplicativo que usa funcionalidades implementadas em bibliotecas estáticas. Aplicações com grandes executáveis sofrem de tempos de inicialização lentos e grandes pegadas de memória. Além disso, quando uma biblioteca estática é atualizada, seus aplicativos clientes não se beneficiam das melhorias feitas a ela. Para ter acesso à funcionalidade melhorada, o desenvolvedor do aplicativo deve vincular os arquivos objeto do aplicativo com a nova versão da biblioteca. E os usuários dos aplicativos teriam que substituir sua cópia do aplicativo pela versão mais recente. Portanto, manter um aplicativo atualizado com a última funcionalidade fornecida pelas bibliotecas estáticas requer um trabalho perturbador tanto pelos desenvolvedores quanto pelos usuários finais.
Uma abordagem melhor é que um aplicativo carregue o código em seu espaço de endereçamento quando ele for realmente necessário, seja na hora do lançamento ou em tempo de execução. O tipo de biblioteca que fornece essa flexibilidade é chamada de biblioteca dinâmica. Bibliotecas dinâmicas não são ligadas estaticamente a aplicativos clientes; elas não se tornam parte do arquivo executável. Ao invés disso, bibliotecas dinâmicas podem ser carregadas (e ligadas) em um aplicativo quando o aplicativo é iniciado ou quando ele é executado.
Figure 2 mostra como implementar algumas funcionalidades como bibliotecas dinâmicas ao invés de como bibliotecas estáticas reduz a memória usada pelo aplicativo após o lançamento.
Usando bibliotecas dinâmicas, os programas podem se beneficiar de melhorias nas bibliotecas que eles usam automaticamente porque sua ligação com as bibliotecas é dinâmica, não estática. Ou seja, a funcionalidade dos aplicativos clientes pode ser melhorada e estendida sem a necessidade de desenvolvedores de aplicativos para recompilar os aplicativos. Os aplicativos escritos para OS X se beneficiam desse recurso porque todas as bibliotecas do sistema no OS X são bibliotecas dinâmicas. É assim que aplicativos que usam tecnologias Carbono ou Cacau se beneficiam de melhorias no OS X.
Uma outra vantagem que as bibliotecas dinâmicas oferecem é que elas podem ser inicializadas quando são carregadas e podem realizar tarefas de limpeza quando o aplicativo cliente termina normalmente. As bibliotecas estáticas não têm este recurso. Para detalhes, veja Module Initializers and Finalizers.
Um problema que os desenvolvedores devem ter em mente ao desenvolver bibliotecas dinâmicas é manter a compatibilidade com aplicativos clientes à medida que uma biblioteca é atualizada. Como uma biblioteca pode ser atualizada sem o conhecimento do desenvolvedor do aplicativo cliente, o aplicativo deve ser capaz de usar a nova versão da biblioteca sem alterações em seu código. Para isso, a API da biblioteca não deve ser alterada. No entanto, há momentos em que as melhorias requerem alterações na API. Nesse caso, a versão anterior da biblioteca deve permanecer no computador do usuário para que o aplicativo cliente possa ser executado corretamente. Dynamic Library Design Guidelines explora o assunto de gerenciamento de compatibilidade com aplicativos clientes à medida que uma biblioteca dinâmica evolui.