Esse artigo faz parte da revista Clube Delphi edição 1. Clique aqui para ler todos os artigos desta edição


Atenção: por essa edição ser muito antiga não há arquivo PDF para download. Os artigos dessa edição estão disponíveis somente através do formato HTML. 

 

Dll’s! Devo mesmo usar?

 

Vamos botar a mão na massa e falar sobre código! Aqui você terá uma coluna dedicada sobre dicas e funções em Delphi, explicadas passo a passo. O tema escolhido este mês foi a Dynamic Library Link, ou como é mais conhecida, DLL. O artigo foi criado no formato pergunta/resposta, para que a leitura ficasse num formato mais dinâmico.

 

Qual a vantagem de se criar umaDLL?

O conceito de DLL (dynamic link library) é bem interessante e seria difícil imaginar um ambiente multitarefa sem este recurso. Basicamente, uma DLL é uma biblioteca de funções, e estas podem ser acessadas por várias aplicações diferentes, ao mesmo tempo. Economiza-se em espaço em disco, pois as funções acessadas por vários aplicativos não estarão repetidas. Não ocupa permanentemente espaço de memória, pois ao acabar de fazer uso da função, o aplicativo pode liberar o espaço ocupado por esta.

 

DLL's ajudam apenas na economia de espaço?

Não. Uma biblioteca dinâmica pode ajudar também de outras formas. Por exemplo: Uma empresa investirá em um projeto relativamente grande, e esta precisa escolher a ferramenta adequada. Provavelmente, alguém levantará a questão: "E se investirmos nesta ferramenta, e a empresa que a produz fechar as portas antes de terminarmos o projeto? Ou se aparecer uma versão mais moderna que não seja compatível com a atual? Teremos que mudar todo o código e recomeçar a programação ?"

Uma DLL resolveria esta questão, e eliminaria a incerteza sobre a ferramenta. Ou seja, o código base e as funções mais complexas poderiam ser armazenadas em DLL's. Caso a mudança fosse necessária, as funções poderiam ser utilizadas a partir da nova ferramenta, sem problemas.

DLL's também ajudam na hora de atualizar o sistema. Seria bem simples dizer ao seu cliente: vá na internet e baixe a nova versão do arquivo 'EnviaTabelaParaBanco dll', caso o banco mude o layout de seus arquivos.

 

DLL's guardam apenas funções?

Não. Você também pode armazenar formulários, ícones, figuras e textos.

 

Outra pessoa pode visualizar e código fonte da minha DLL?

A princípio, não. A DLL é compilada como um executável.

Siga os procedimentos e veja como criar uma DLL:

No Delphi 6, selecione o menu File, New. No repositório de objetos, dê um clique duplo no ícone,um novo projeto será criado, com apenas uma unidade, que deverá se parecer com o código abaixo:

 

library Project1;

 

uses

   SysUtils,

   Classes;

   begin

end.

 

Repare que a primeira linha apresenta a palavra-chave Library, em vez de Unit.

Agora, incluiremos as funções, abaixo da cláusula USES e salvaremos com o nome de Decimal_binario_Dll. As funções utilizadas como exemplo servem para converter de decimal para binário, e vice-versa:

 

library Project1;

uses

SysUtils,

Classes;

function Potencia(numero,potencia:integer):integer;

var

cont:Integer;

begin

  if (potencia=0) or (numero=0) then

  result:=0

Else

begin

  result:=numero;

  for cont:=2 to potencia do

  result:=result * numero;

End;

End;

 

Function BinarioParaDecimal (binario:String):Integer;stdcall;

var

cont:Integer;

begin

  result:=0;

  for cont:=Length(binario) downto 1 do

  begin

    result:=result + potencia(2 * STrToInt(binario[cont]),length(binario)-cont);

  end;

end;

function DecimalParaBinario(decimal:integer):String;stdcall;

var

binario,r:String;

cont,resto, quociente:Integer;

begin

  binario:=’’;

  result:=’’;

  r:=’’;

while decimal>=2 do

begin

  quociente:=decimal div 2;

  resto:=decimal mod 2;

  binario:=binario+IntToStr(resto);

  decimal:=quociente;

  if decimal=1 then

  binario:=binario+IntTostr(quociente);

End;

for cont:=Length(binario) downto 0 do

r := r + binario[cont];

result:=r;

end;

exports

BinarioParaDecimal index 1,

DecimalParaBinario index 2;

{$R *.res}

begin

end.

 

A sintaxe é bem simples: basta criar a cláusula exports e definir o nome das funções que serão exportadas.

Note que após o cabeçalho da função que será exportada, aparece a cláusula stdcall. Stdcall significa que a linguagem que se utilizar desta função deverá passar os parâmetros da forma convencional, ou seja, da direita para a esquerda.

Repare também que a função potência é apenas de uso interno, e não será exportada pela DLL.

O parâmetro index serve como alternativa para identificação da função.

Após, basta compilar a unidade e o Delphi criará o arquivo .dll, com o nome do projeto e no diretório em que este foi salvo.

 

Importando as funções de uma DLL

Agora que já vimos como criar a DLL e exportar suas funções, veremos como usá-las através do Delphi. Existem dois métodos de acesso: estático e dinâmico. No método estático temos vantagens e desvantagens :

Desvantagens : A DLL é carregada juntamente com o programa causando evidente desperdício de memória até o encerramento do aplicativo, e seu sistema fica escravo da Dll, sem ela o mesmo não executa.

A vantagem é que este método é mais fácil de ser implementado.

 

No método dinâmico a DLL pode ser carregada e descarregada de acordo com a necessidade, poupando memória. Porém, a implementação do método dinâmico é mais complexo. Veremos os dois:

 

Método Estático:

Para acessar uma função externa usando este método, basta declarar o cabeçalho da função logo abaixo da seção implementation, como mostrado abaixo:

 

implementation

Function DecimalParaBinario(decimal:Integer): String; stdcall;external 'NomeDoArquivo.DLL';

 

{$R *.dfm}

 

O comando stdcall, indica que os parâmetros serão passados para a função da forma convencional. A cláusula external indica o arquivo em que a função se encontra.

E após, a função pode ser utilizada normalmente como se estivesse no programa.

 

Método Dinâmico:

Este método é um pouco mais trabalhoso. Primeiramente, devemos criar um ponteiro que receberá o cabeçalho da função:

Type

TDecimalParaBinario = function(decimal:Integer):string;

 

Devemos criar também uma variável do tipo handle, que receberá o handle da DLL:

 

var

  Form1: TForm1;

  DecimalParaBinario : TDecimalParaBinario;

  hdl : Thandle;

implementation

 

{$R *.dfm}

 

procedure TForm1.FormShow(Sender: TObject);

Begin

  Hdl:=LoadLibrary(‘Decimal_Binario.dll’);

  @DecimalParaBinario := GetProcAddress(hdl,’DecimalParaBinario’);

End;

 

Primeiramente, pegamos o handle da dll com a API LoadLibrary; Após atribuímos o endereço da função desejada (DecimalParaBinario) a variável DecimalParaBinario, declarada anteriormente. Para recuperar este endereço, usamos a API GetProcAddress. Devemos passar o handle do arquivo, e o nome da função para esta API.

Após a variável DecimalParaBinario ser inicializada pela função GetProcAddress, esta pode ser utilizada normalmente como se estivesse local ao programa:

 

Procedure Tform1.button1click

(sender:tobject);

Begin

Edit1.text:=DecimalParaBinario(20);

End;

 

Quando a dll não for mais necessária, basta chamar a Api FreeLibrary, para que esta seja liberada da memória:

 

FreeLibrary(hdl);

 

Adicionando um formulário a DLL:

Além de funções, uma DLL pode conter gráficos, textos, ícones, e até mesmo formulários. Para incluir um formulário, por exemplo, basta incluir uma unidade no projeto, clicando no menu Fileà Newà Form.  Após , crie um procedimento exportado

que chame este formulário:

 

procedure exibe; stdcall;export;

begin

  Application.CreateForm(TForm1,Form1);

  form1.showmodal;

  form1.free;

End;

 

Repare que o formulário precisa ser criado, com o método Crateform, do objeto TApplication. Como vimos, o uso e criação de DLLs no Delphi são muito fáceis

de serem implementados. DLLs, quando bem utilizadas, podem melhorar o desempenho de suas aplicações. Na hora de fazer seu projeto, não deixe de analisar como este

recurso poderá ajudá-lo.

 

Dúvidas ou opiniões sobre este tópico

podem ser enviadas para: admin@clubedelphi.com.br