Entendendo a instalação de componentes

Qualidade: 

Estrela ativaEstrela ativaEstrela ativaEstrela ativaEstrela ativa
 

Páginas neste artigo

Tipos de arquivo que o Delphi manipula

Gostaria de fazer uma revisão sobre os tipos de arquivos que o Delphi gera ou manipula dentro do contexto dos pacotes. É importante conhecê-los para não cometer erros ao instalar componentes e, principalmente, conhecer seus significados a fim de saber como referenciá-los no Library Path. Sem mais delongas, ei-los:

Extensão Descrição
Arquivos de código-fonte (arquivos de texto plano)
.dpk Delphi Package Project File - Este é o arquivo de projeto principal de um pacote. Em comparação com um projeto padrão do Delphi, este arquivo equivale ao arquivo .dpr (Delphi Project). O arquivo de projeto de um pacote contém várias configurações adicionais, ao contrário do arquivo .dpr. A maioria destas configurações pode ser modificada por meio da caixa de diálogo "Project Options". Algumas das configurações mais básicas encontram-se no item (ou aba) "Description" desta caixa de diálogo, cujos campos que merecem destaque são: Description, Usage options e LIB suffix. Falarei mais a respeito destas opções posteriormente neste artigo
.pas Pascal Source File - Todo e qualquer projeto Delphi, seja um pacote, um executável, ou uma biblioteca, normalmente possui ao menos um arquivo de fonte. Bibliotecas (dll) ou aplicações de console, quando muito simples, podem conter apenas o arquivo .dpr, sem qualquer arquivo .pas. O arquivo .dpr, pode conter o fonte completo, mas por organização você não vai querer que todo o seu programa seja escrito em um único arquivo, logo, é desejável sempre ter ao menos um arquivo .pas para organizar seu código-fonte. Arquivos .pas são compiláveis e ao serem compilados geram arquivos .dcu como resultado
.inc Include File - Um arquivo de inclusão pode ter qualquer extensão, mas convenciona-se que arquivos desta natureza tenham a extensão .inc. O uso mais comum dos arquivos de inclusão é o agrupamento de diretivas de compilação, mas eles são bem mais que isso. Arquivos de inclusão são arquivos de texto plano que podem conter basicamente qualquer coisa que você colocaria em um arquivo .pas, mas com uma diferença muito importante: arquivos usados como arquivos de inclusão NÃO SÃO COMPILADOS SOZINHOS como os arquivos .pas, eles precisam ser incluídos em algum fonte compilável. Esta característica, que a princípio parece ser uma desvantagem, na verdade permite que arquivos de inclusão possuam trechos completos de código, classes, constantes, variáveis e qualquer outro tipo de código-fonte que podem ser incluídos em pontos específicos de arquivos .pas, sem necessidade de replicar código.

Como um exemplo bem simples e, por isso mesmo, não tão usual, suponha que você possui uma mensagem que precisa ser exibida da mesma forma em vários locais distintos dentro do seu código-fonte. Você pode escrever um arquivo minhamensagem.inc da seguinte maneira:
Application.MessageBox('Eu fui definida em um arquivo .inc'
                      ,'Mensagem do arquivo de inclusão'
                      ,MB_ICONWARNING);
Posteriormente você pode em um código-fonte propriamente dito (arquivo .pas) inclur este seu arquivo .inc, em um ponto do código-fonte onde ele faz sentido, isto é, em um local onde o conteúdo do arquivo .inc, SE FOSSE DIGITADO, seria correto. Como no arquivo .inc há apenas a chamada a Application.MessageBox, nós podemos incluir nosso arquivo em um local onde a chamada a esta função pode ser aplicada, por exemplo, o clique de um botão:
procedure TForm1.Button1Click(Sender: TObject);
begin
  {$i minhamensagem.inc}
end;
Como se pode ver, para referenciar um arquivo de inclusão, se usa a diretiva {$I nomedoarquivo.inc}. A grande vantagem dos arquivos de inclusão só é percebida quando se entende que o trecho de código acima, na verdade é interpretado pelo compilador como:
procedure TForm1.Button1Click(Sender: TObject);
begin
  Application.MessageBox('Eu fui definida em um arquivo .inc'
                      ,'Mensagem do arquivo de inclusão'
                      ,MB_ICONWARNING);
end;
Como se pode observar o conteúdo do arquivo de inclusão é "digitado" no local onde ele for incluído, logo, o ponto no código-fonte onde arquivos de inclusão podem ser colocados depende unicamente de seu conteúdo. Você poderia colocar uma classe inteira, com todos os seus métodos definidos, dentro de um arquivo de inclusão, no entanto ele não poderia ser incluído dentro do clique de um botão, pois se você substituir, na posição do include, o conteúdo do arquivo de inclusão, o fonte .pas não vai compilar.
Arquivos gerados (arquivos binários)
.dcu Delphi Compiled Unit - Todo arquivo .pas, ao ser compilado, gera um arquivo correspondente .dcu. Arquivos .dcu, em outras palavras, são a versão binária de um arquivo .pas. Linguagens como C e C++, possuem um arquivo chamado .obj que são gerados a partir de arquivos .c ou .cpp. Pode-se dizer que arquivos .dcu estão para arquivos .pas assim como arquivos .obj estão para arquivos .c ou .cpp. Arquivos .dcu são diferentes quando compilados por compiladores diferentes, isto é, se você tem um mesmo fonte .pas e compila este fonte no Delphi 2006 e no Delphi XE5, os arquivos .dcu gerados serão completamente diferentes, apesar de fazerem a mesma coisa. É este um dos motivos pelos quais não se pode instalar componentes sem fontes (sem arquivos .pas) em qualquer Delphi, porque os arquivos .pas, .bpl e .dcp são dependentes da versão do compilador e simplesmente são incompatíveis. Você só consegue instalar componentes sem fontes, quando estes 3 arquivos foram compilados exclusivamente para a versão do Delphi onde você pretende instalá-los
.bpl Borland Package Library - Arquivos de projeto .dpr geram arquivos .exe ou .dll. Arquivos de projeto .dpk geram sempre dois arquivos. Um deles é o arquivo .bpl o outro é o arquivo .dcp (vide próximo ítem). Arquivos .bpl estão para projetos .dpk assim como arquivos .exe e .dll estão para projetos .dpr, logo, os arquivos .bpl são o resultado final mais importante da compilação de um pacote. Eles se assemelham estruturalmente a uma dll e como tal podem ser carregados por executáveis (Runtime Packages) e, no seu uso mais simples, carregadas pelo próprio Delphi (Designtime Packages). O carregamento por executáveis não será coberto neste artigo, apenas o carregamento simples, pela IDE, o qual é essencial para o entendimento de como ocorre a instalação de pacotes. Quando um pacote é instalado, na verdade, nós estamos informando ao Delphi que aquele determinado arquivo .bpl gerado, deve ser carregado pela IDE. A instalação deste arquivo fará com que componentes apareçam na paleta de componentes e experts/wizards sejam registrados (vide artigo Open Tools API).
.dcp Delphi compiled package - O arquivo .dcp é gerado juntamente com o arquivo .bpl. Ele é um arquivo binário especial que contém o cabeçalho do pacote BPL e a concatenação de todos os arquivos .dcu deste pacote, bem como toda informação necessária requerida pelo compilador e pelo ligador (linker).

Como se pode observar, o arquivo .dcp é como se fosse um resumo binário de todo o código-fonte do pacote, por isso, uma característica muito interessante deste arquivo é que ele substitui a presença de todos os arquivos .dcu que ele contém! De fato, quando um pacote faz referência em sua cláusula requires (veja mais adiante) a um arquivo .dcp, este pacote pode usar units que estão neste arquivo .dcp, como se as units compiladas (.dcu) estivessem fisicamente disponíveis! Em suma, eu não preciso ter nenhum arquivo .dcu disponível, caso eu possua o arquivo .dcp que o contenha.

O papel do arquivo .dcp é muito relevante dentro desenvolvimento de pacotes no Delphi. Os arquivos .dpk possuem uma seção especial chamada requires, na qual outros pacotes são referenciados, veja:


Como se pode ver, este pacote possui 3 dependências de outros pacotes. Significa que dentro do pacote nós estamos usando componentes, funções ou recursos de uma forma geral que estão disponíveis em outros pacotes. No pacote do exemplo acima eu estou fazendo referências ao TClientDataSet, o qual é definido na unit DBClient que foi compilada no pacote dsnapXXX.bpl1 e por isso eu preciso fazer referência direta ao "resumo" deste pacote. Para isso eu uso seu arquivo .dcp correspondente (dsnap.dcp2) na cláusula requires do .dpk, pois dentro de dsnap.dcp existe o arquivo DBClient.dcu.

Apesar de eu estar falando que o arquivo .dcu está dentro do arquivo .dcp, isso é apenas para facilitar o entendimento. Arquivos .dcp não são contêineres, logo, não é possível extrair um arquivo .dcu de dentro do arquivo .dcp. O arquivo .dcp possui todo conteúdo binário de todos os arquivos .dcu de um pacote. O Delphi, seu compilador e seu linker fazem referência a parte desse código de forma nomeada, usando o mesmo nome da unit original, por exemplo, dentro de um pacote que requer dsnap.dcp, caso em uma unit eu declare na cláusula uses DBClient, o Delphi vai saber que o código desta unit está disponível. No momento da compilação, o compilador entende que deve procurar o código binário de DBClient dentro de dsnap.dcp.

Arquivos .dcp são muito importantes quando precisamos nos referenciar ao nosso pacote a partir de outro, logo, isso não é algo que um iniciante no desenvolvimento de componentes vá fazer, portanto, não precisa se preocupar com os arquivos .dcp no momento. Apenas entenda que eles são necessários e não devem ser negligenciados.
Arquivos de recurso (arquivos binários e de texto plano)
.res / .dcr Resource File - Arquivos de recurso com a extensão .res ou .dcr são arquivos binários que podem conter ícones, cursores, imagens, strings, teclas de atalho, menus, caixas de diálogo, dados binários sem formato específico (raw) e informações de versão. Normalmente no Delphi você não precisa se preocupar com arquivos de recurso, pois eles são criados automaticamente e incluídos no binário final (.exe, .dll, .bpl), contudo, ao desenvolver componentes especificamente, eventualmente você vai precisar incluir ao menos recursos de imagem e ícones no seu BPL e a única forma de fazer isso é por meio do uso de arquivos de recurso. Você pode criar um arquivo .res / .dcr usando um editor de recursos e vincular este arquivo de recurso ao seu projeto, incluindo a diretiva {$R nomedoarquivo.res} ou {$R nomedoarquivo.dcr} em algum fonte do mesmo (ou no seu arquivo de projeto). A inclusão pode usar um arquivo de texto plano também (vide .rc abaixo). Não existem diferenças práticas entre um .dcr e um .res, apenas convenciona-se usar a extensão .dcr para indicar um arquivo de recurso que possui os ícones de um componente que serão apresentados na paleta de componente do Delphi. DCR significa "Delphi Component Resource"
.rc Compiler Resource File - Arquivos de recurso com a extensão .rc são arquivos de texto plano e que podem ser considerados "código-fonte" de recurso, pois é possível gerar um arquivo .res a partir de um arquivo .rc utilizando um compilador de recurso (Resource Compiler). A extensão .rc, portanto, remete ao nome Resource Compiler, já que este arquivo sempre precisa ser compilado antes de ser usado. Arquivos .rc podem conter exatamente os mesmos itens que um arquivo .res, a diferença é que estes ítens são incluídos no arquivo .rc de forma textual, "legível por humanos". Arquivos .rc não podem ser vinculados diretamente a um binário, tal como acontece com os arquivos .res, é necessário compilá-lo antes e, por este motivo, o Delphi possui uma sintaxe especial da diretiva {$R} que permite compilar e vincular um arquivo .rc. Utilizando {$R nomedoarquivo.res nomedoarquivo.rc}nomedoarquivo.rc será automaticamente compilado e gerará o arquivo nomedoarquivo.res, o qual, finalmente, será vinculado pela diretiva
.dfm Delphi Form File - Você deve estar se perguntando porque arquivos .dfm estão incluídos nesta lista de recursos, bom, se segure na cadeira meu caro, mas arquivos .dfm são arquivos de recurso! Você não leu errado. Arquivos .dfm são arquivos de recurso especiais e exclusivos do Delphi e que contém referências a todas as propriedades publicadss do TForm e de todos os componentes nele incluídos. Propriedades publicadas, ou published, são propriedades que geram Informações de Tipo em Tempo de Execução, ou RTTI. Se você abrir um executável, por exemplo, em um editor de recurso, e for na seção RCData, você verá todos os seus formulários lá, veja:


Note que as propriedades publicadas do TForm aparecem, bem como as propriedades publicadas de outros componentes inseridos no TForm, tal como o TButton que se pode ver na imagem acima. Você deve estar pensando agora se é possível modificar algumas destas propriedades diretamente no arquivo binário usando o editor de recurso, e, bem, sim, isso é totalmente possível! Qualquer uma destas propriedades pode ser alterada e salva diretamente no arquivo binário, no caso no .exe, sem necessidade de recompilá-lo, e isso vai alterar o resultado da aplicação em tempo de execução, porém, devo alertar que algumas coisas não devem ser alteradas, sob pena de você inutilizar seu executável. Arquivos .dfm podem ser salvos de forma binária o que não é recomendável, mas mesmo quando eles são salvos desta forma, dentro do binário compilado sua representação sempre é textual. Isso significa que o modo binário de salvamento de arquivos .dfm só afeta de fato o arquivo em si e não a forma como ele é vinculado ao projeto finalizado (.exe, .dll ou .bpl).

Outra prova inegável de que arquivos .dfm são, também, arquivos de recuso, é a forma como eles são vinculados aos projetos. Se você criar um projeto novo e olhar o código-fonte do único formulário você verá a seguinte linha {$R *.dfm}. A diretiva {$R} você já conhece, ela serve para vincular um arquivo de recurso ao projeto, logo, o nome de arquivo que vem depois dela, é um arquivo de recurso. Mas tem algo diferente, você diz, "não existe um nome de arquivo, mas sim um caractere curinga com a extensão .dfm". Se você pensou isso você está errado. O asterisco parece, mas não é um caractere curinga e *.dfm não significa, portanto, todos os arquivos com extensão .dfm. A diretiva {$R} interpreta o asterisco como sendo o nome-base da unit atual, isto é, o nome da unit sem a extensão, logo, se sua unit se chama UFormPrincipal.pas, usar a diretiva {$R *.dfm} nela vai instruir ao Delphi para vincular ao projeto o arquivo UFormPrincipal.dfm. É por este motivo que toda vez que você salva a unit de um TForm, um arquivo .dfm de mesmo nome será gerado juntamente com ela. Se você alterar a diretiva e colocar o nome do arquivo .dfm completo, vai funcionar do mesmo modo, no entanto, isso é desencorajado, na maioria das situações, quando você não sabe o que está fazendo, pois, caso você altere o nome da unit, um novo .dfm será criado para ela, mas, internamente, ela estará vinculada a um outro arquivo .dfm, o que pode gerar uma grande confusão. O caractere especial "*" também pode ser usado ao fazer referência a um arquivo .res propriamente dito, tendo, pois, o mesmo significado!

Para saber um pouco mais sobre RTTI, arquivos .dfm e um uso inusitado dessa combinação de tecnologias, leia o artigo Serialização de Objetos & Persistência em Arquivos.
 
Está gostando do que está lendo? Ajude nosso site visitando nossos patrocinadores. Obrigado! :)

Arquivos gerados pela compilação de um pacote

Ao contrário de um executável ou de um biblioteca (dll) a compilação de um pacote gera 3 tipos de arquivo importantes:

  • Arquivo BPL - Cada pacote gera um e apenas um arquivo BPL. Arquivos BPL podem ser compilados de acordo com o uso que eles terão. Esta configuração chama-se "Usage Option" e está disponível no item (ou aba) "Description" da caixa de diálogo "Project Options". Existem 3 formas de uso para um BPL:

    • Designtime Only - BPLs desse tipo são desenvolvidos para serem instalados na IDE e por este motivo eles normalmente possuem apenas código que só faz sentido dentro da IDE. Este código inclui basicamente editores de componente, editores de propriedade e código de registro que normalmente é colocado dentro do procedure especial "Register". Não é comum desenvolver um BPL deste tipo que não contenha alguns destes códigos específicos. Se sua intenção é desenvolver um pacote que contenha apenas units e funções utilizáveis por projetos, você deve desenvolver um pacote "Runtime Only"

    • Runtime Only - BPLs desse tipo são desenvolvidos para serem usados como pacote em tempo de execução por executáveis ou internamente pela IDE em tempo de desenvolvimento por projetos. Este tipo de BPL não é instalável, então ele não pode conter códigos dos tipos mencionados no item anterior (Designtime Only). Pacotes deste tipo podem conter, portanto, todo o restante de possíveis códigos, incluindo o código de componentes que são instalados em pacotes do tipo Designtime Only

    • Designtime and Runtime - BPLs deste tipo possuem uma junção de características dos dois tipos anteriores. Em outras palavras, pacotes deste tipo contém componentes e também podem ser carregados por executáveis em tempo de execução
  • Arquivo DCP - Arquivos de "índice" para o pacote sendo compilado (BPL). Vide explicação sobre arquivos .dcp na tabela acima.
  • Arquivo DCU - Arquivos de fonte compilados (arquivos .pas compilados). Vide explicação sobre arquivos .dcu na tabela acima. Os arquivos .dcu são tão importantes em um pacote quanto o próprio arquivo .bpl que é gerado. Enquanto para um executável normal ou biblioteca, arquivos .dcu são apenas arquivos intermediários, para os pacotes estes arquivos são essenciais para que o componente possa ser usado. Arquivos .dcu de um pacote são SEMPRE arquivos intermediários de outros projetos que usam units desse pacote. De forma mais simples, arquivos .dcu de um componente são arquivos intermediários quando compilamos projetos que usam este componente e é por isso que os arquivos .dcu de um pacote precisam sempre estar disponíveis via "paths do Delphi" (leia mais adiante)
1Dependendo da configuração da propriedade Lib Suffix o XXX pode ser substituído por uma string qualquer. Normalmente o Lib Suffix indica a versão do compilador. Por exemplo, se este pacote tivesse sido compilado no Delphi 2006, o nome do BPL gerado deveria ser dsnap100.bpl, pois a versão do compilador do Delphi 2006 é 10
2Arquivos DCP, ao contrário dos arquivos BPL não recebem o Lib Suffix, o qual é usado apenas nas saídas principais do compilador, isto é, apenas arquivos .exe, .dll e .bpl utilizam o Lib Suffix para formar o nome do arquivo
Ajude nosso site visitando nossos patrocinadores!

Temos 107 visitantes e um membro online nos últimos 10 minutos (10.8 visitantes por minuto). O membro online é:

admin