Você já usou o Adobe Photoshop? Para os leigos, os plugins são apenas blocos de código fornecidos ao aplicativo de fora (por exemplo, em uma DLL). A diferença entre um plug -in e uma DLL normal é que o plug -in tem a capacidade de estender a funcionalidade do aplicativo pai. Por exemplo, o próprio Photoshop não possui uma grande quantidade de funções de processamento de imagem. A adição de plug-ins oferece um efeito incrível, como Blur, Spot e todos os outros estilos, e nenhum deles possui o próprio aplicativo pai.
Isso é muito bom para programas de processamento de imagens, mas por que você precisa gastar muito esforço para concluir aplicativos comerciais que suportam plugins? Suponha que, vamos dar um exemplo, seu aplicativo gerará alguns relatórios. Seus clientes definitivamente continuarão pedindo atualizações ou adicionando novos relatórios. Você pode usar um gerador de relatório externo, como o relatório Smith, que é uma solução não tão parecida com muito tipo, requer publicação de arquivos adicionais, treinamento adicional para usuários e assim por diante. Você também pode usar o QuickReport, mas isso o colocará em um pesadelo de controle de versão - se você deseja reconstruir seu aplicativo toda vez que alterar a fonte.
No entanto, desde que você transforme o relatório no plug -in, poderá usá -lo. Precisa de um novo relatório? Não tem problema, basta instalar uma DLL e você verá na próxima vez que o aplicativo iniciar. Outro exemplo é um aplicativo que processa dados de dispositivos externos (como scanners de código de barras). Ao escrever cada rotina de processamento de interface do dispositivo como plug-in, você pode obter a máxima escalabilidade sem fazer alterações no aplicativo pai.
começando
A coisa mais importante antes de começar a escrever o código é descobrir quais recursos seu aplicativo precisa estender. Isso ocorre porque o plug -in interage com o aplicativo pai por meio de uma interface específica, que será definida de acordo com suas necessidades. Neste artigo, criaremos 3 plugins para mostrar várias maneiras pelas quais o plug -in interage com o aplicativo pai.
Vamos transformar o plug -in em uma DLL. Antes de fazer isso, porém, temos que fazer uma concha para carregá -los e testá -los. A Figura 1 mostra o programa de teste após o carregamento do primeiro plug-in. O primeiro plug -in não realiza nada grande e, de fato, tudo o que faz é retornar uma string que se descreve. No entanto, confirma um ponto importante-funcionará corretamente com ou sem aplicativos de plug-in. Se não houver plug-in, ele não aparecerá na lista de plug-ins instalados, mas o aplicativo ainda pode executar funções normalmente.
A única diferença entre nosso shell plug-in e aplicativos normais é a unidade Sharemem no arquivo de origem do projeto que aparece na cláusula de uso e no código que carrega o arquivo plug-in. Qualquer aplicativo que passa os parâmetros de string entre si e a DLL da criança? Para testar este shell, você precisa copiar o arquivo Delphimm.dll do diretório Delphi/Bin para o caminho contido na variável do ambiente do caminho ou no diretório em que o aplicativo está localizado. O arquivo também deve ser distribuído ao mesmo tempo em que a versão final é lançada.
O plug-in é carregado nesse shell de teste através do processo LoadPlugins, chamado no evento FormCreate na janela principal, veja a Figura 2. Esse processo usa funções FindFirst e FindNext para encontrar arquivos de plug -in no diretório em que o aplicativo está localizado. Depois de encontrar um arquivo, use o processo LoadPlugins mostrado na Figura 3 para carregá -lo.
{Encontre arquivos de plug -in no diretório do aplicativo}
Procedimento tfrmmAin.loadplugins;
var
SR: TSearchRec;
caminho: string;
Encontrado: Inteiro;
Começar
Caminho: = ExtractFilePath (Application.Exename);
tentar
Encontrado: = findFirst (caminho + cplugin_mask, 0, sr);
enquanto encontrado = 0 começa
Loadplugin (SR);
Encontrado: = findNext (sr);
fim;
Finalmente
FindClose (SR);
fim;
fim;
{Carregue a dll do plug -in especificada.
procedimento tfrmMain.loadplugin (sr: tSearchRec);
var
Descrição: string;
Libhandle: Inteiro;
Descreverproc: tplugIndescribe;
Começar
Libhandle: = loadlibrary (pchar (sr.name));
se libhandle $#@60; $#@62;
Começar
DescrepProc: = getProcaddress (libhandle, cplugin_describe);
Se atribuído (descreverproc), então
DescriçãoProc (Descrição);
Memplugins.Lines.add (Descrição);
fim
outro
Começar
Messagedlg ('arquivo "' + sr.name + '" não é um plug-in válido.',
mtinformation, [mBok], 0);
fim;
fim
outro
Messagedlg ('Ocorreu um erro carregando o plug-in "' +
sr.name + '".', mterror, [mbok], 0);
fim;
O método Loadplugin demonstra o núcleo do mecanismo de plug-in. Primeiro, o plug -in é escrito como uma DLL. Em segundo lugar, ele é carregado dinamicamente através da API de libernaria de carga. Depois que a DLL for carregada, precisamos de uma maneira de acessar os procedimentos e funções que ele contém. As chamadas da API getProcaddress fornecem esse mecanismo, que retorna um ponteiro para a rotina necessária. Em nossa demonstração simples, o plug -in contém apenas um procedimento chamado DescrevePplugin, especificado pelo constante Cplugin_Describe (o caso do nome do procedimento é muito importante, e o nome passado para GetProcaddress deve ser exatamente o mesmo que o nome de rotina incluído na DLL) . Se nenhuma rotina solicitada for encontrada na DLL, o GetProcaddree retornará nulo, para que você concorde em usar a função atribuída para determinar o valor de retorno.
Para armazenar ponteiros para uma função de uma maneira fácil de usar, é necessário criar um tipo específico para as variáveis usadas. Observe que o valor de retorno do getProcAddress é armazenado em uma variável, descrevem, pertence ao tipo tplugIndescribe. Aqui está sua declaração:
tipo
TplugIndescribe = Procedimento (VAR DESC: String);
Como o procedimento existe dentro da DLL, ele compila todas as rotinas de exportação por meio de conversões de chamadas padrão, para que o indicador StdCall seja necessário. Esse processo usa um parâmetro var, que contém a descrição do plug -in quando o processo retorna.
Para chamar o processo que você acabou de obter, basta usar a variável que salva o endereço como o nome do processo, seguido por qualquer parâmetros. No nosso caso, a declaração:
DescriçãoProc (Descrição)
O processo de descrição obtido no plug-in será chamado e a variável de descrição é preenchida com uma string descrevendo a funcionalidade do plug-in.
Plug-in de construção
Criamos o aplicativo pai e é hora de criar o plug -in que queremos carregar. O arquivo do plug -in é uma DLL Delphi padrão, por isso criamos um novo projeto DLL a partir do Delphi IDE e o salvamos. Como a função de plug-in exportada usará parâmetros de string, a unidade do compartilhamento deve ser colocada em primeiro lugar na cláusula de uso do projeto. A Figura 4 lista o arquivo de origem do projeto do nosso plug-in simples.
usos
Sharemem, sysutils, aulas,
principal em 'main.pas';
{$ E plg.}
exportações
Descrever plugin;
Começar
fim.
Embora o plug -in seja um arquivo DLL, não há necessidade de fornecer uma extensão .dll. De fato, um motivo é suficiente para nos dar um motivo para alterar a extensão: quando o aplicativo pai procura o arquivo a ser carregado, a nova extensão pode servir como uma máscara de arquivo específica. Ao usar outra extensão (nosso exemplo usa *.plg), você pode estar um pouco confiante de que o aplicativo carregará apenas os arquivos correspondentes. O indicador de compilação $ x pode alcançar essa alteração ou você pode definir a extensão através da página de aplicativo da caixa de diálogo Opções do projeto.
O código para o primeiro exemplo do plug -in é muito simples. A Figura 5 mostra o código contido em uma nova unidade. Observe que o protótipo DecledPlugin é consistente com o tipo TPLUGINDescribe no aplicativo Shell e usa a palavra de exportação adicional para especificar que o processo será exportado. O nome do processo exportado também aparecerá na seção de exportação do código -fonte principal do projeto (listado na Figura 4).
unidade principal;
interface
Procedimento DescreppluGin (var descr: string);
exportação;
Implementação
Procedimento DescreppluGin (var descr: string);
Começar
Desc: = 'Plugin de teste v1.00';
fim;
fim.
Antes de testar este plug -in, copie -o para o caminho do aplicativo principal. A maneira mais fácil é criar um plug-in no subdiretório do diretório inicial e definir o caminho de saída para o caminho principal (os diretórios/condicionais da caixa de diálogo Opções do projeto também podem ser usados para essa configuração).
depurar
Agora, deixe -me apresentar um recurso melhor em Delphi 3: a capacidade de depurar DLLs do IDE. Em um projeto DLL, você pode especificar um programa como o aplicativo host através da caixa de diálogo Run Paramates. Em seguida, você pode definir pontos de interrupção no seu código DLL e pressionar F9 para executá -lo - assim como você faria em um aplicativo normal. A Delphi executará o programa de host especificado e, compilando a DLL com informações de depuração, direcionará o ponto de interrupção no código DLL.