A produção de uma DLL geralmente é dividida nas seguintes etapas:
1 Escreva um procedimento ou função em um projeto DLL
2 Escreva uma palavra-chave Exports e escreva o nome do procedimento abaixo dela. Não há necessidade de escrever parâmetros e chamar sufixos.
Dois parâmetros passados
1 O tipo de parâmetro deve ser consistente com o tipo de parâmetro da janela C++. Não use o tipo de dados DELPHI.
2 É melhor ter um valor de retorno [mesmo que seja um procedimento] para relatar o sucesso ou falha da chamada, ou o status. O valor de retorno de sucesso ou falha é preferencialmente 1 [sucesso] ou 0 [falha].
3 Declare o sufixo com stdcall.
4 De preferência com distinção entre maiúsculas e minúsculas.
5 Não há necessidade de usar o sufixo de chamada remota, ele é apenas para compatibilidade com programas do Windows de 16 bits.
Inicialização e limpeza de saída de três DLLs [se a inicialização e a limpeza de saída forem necessárias]
1 DLLPRoc [um ponteiro da unidade SysUtils] é a entrada para a DLL. Aqui você pode substituir sua entrada pela sua função. Mas sua função deve atender aos seguintes requisitos [na verdade, uma função de retorno de chamada]. do seguinte modo:
procedimento DllEnterPoint(dwReason: DWord);far;stdcall;
Existem quatro tipos de parâmetros dwReason:
DLL_PROCESS_ATTACH: Quando o processo entra
DLL_PROCESS_DETACH quando o processo termina
DLL_THREAD_ATTACH quando o thread entra
DLL_THREAD_DETACH quando o thread termina
Na seção de inicialização escreva:
DLLProc := @DLLEnterPoint;
DllEnterPoint(DLL_PROCESS_ATTACH);
2 Caso exista o componente TdcomConnection no Form, utilize Usa Activex e escreva CoInitialize (nil) durante a inicialização;
3 Certifique-se de que DcomConnection.Connected := False ao sair e que o conjunto de dados tenha sido fechado. Caso contrário, o endereço informado está errado.
O uso de quatro variáveis globais
No programa Widnows de 32 bits, os espaços de endereço dos dois aplicativos não estão relacionados entre si. Embora a DLL seja uma cópia na memória, as variáveis estão no espaço de endereço de cada processo, portanto você não pode usar as variáveis globais da dll para transferir dados entre dois aplicativos, a menos que use um arquivo de imagem de memória.
5. Chame o carregamento estático
1 Declaração de função do cliente:
1) Diferencia maiúsculas de minúsculas.
2) Igual à declaração na DLL.
Tais como: showform(form:Tform);Far;external'yproject_dll.dll';
3) O tipo de parâmetro passado na chamada deve ser o mesmo do Windows C++.
4) Ao chamar, a DLL deve estar no caminho de pesquisa do Windows. A ordem é: caminho do diretório atual windows/system;
Seis chamadas para carregamento dinâmico
1 Crie um tipo de procedimento [Se você tiver certeza de que a natureza de uma variável de tipo de procedimento é apenas um ponteiro, você saberá o que está acontecendo]. como:
tipo
meuponteiro=procedimento(form:Tform);Far;externo;
var
Dica:Thandle;
showform:meuponteiro;
começar
Hinst:=loadlibrary('yproject_dll');//Carregue uma DLL e encontre-a pelo nome do arquivo.
showform:=getprocaddress(Hinst,'showform');//Encontre pelo nome da função, diferenciando maiúsculas de minúsculas. Isso fica claro se você conhece a natureza dos objetos de automação.
showform(application.mainform);//Chamado ao encontrar o ponteiro de entrada da função.
Biblioteca Livre(Hinst);
fim;
7. Crie um TForM na DLL
1 Usa seu formulário em DLL, e as unidades associadas usadas pelo seu formulário também devem ser usadas em [Este é o ponto mais problemático, porque seu formulário pode usar muitas unidades ou funções especiais]
2 Passe um parâmetro Application e utilize-o para criar o Form.
8. Crie um TMDIChildForM na DLL
1 MDIForm.FormStyle em DLL não precisa ser fmMDIChild.
2 Escreva as duas frases a seguir após CreateForm:
função ShowForm(mainForm:TForm):integer;stdcall
var
Formulário1: TForm1;
ptr:PLongInt;
começar
ptr:=@(Application.MainForm);//Salve o identificador MainForm da dll primeiro, não há necessidade de liberá-lo, apenas substitua-o
ptr^:=LongInt(mainForm);//Substitua o MainForm da DLL pelo mainForm do programa chamador. MainForm é uma JANELA especial que gerencia especificamente recursos de Formulários no Aplicativo.
//Por que não diretamente Application.MainForm := mainForm, porque Application.MainForm é uma propriedade somente leitura
Form1:=TForm1.Create(mainForm);//Criar com parâmetros
fim;
Nota: O parâmetro é Application.MainForm do programa chamador
Nove exemplos:
Código-fonte da DLL:
biblioteca Projeto2;
usa
SysUtils,
Aulas,
Diálogos,
Formulários,
Unidade2 em 'Unit2.pas' {Form2};
{$R *.RES}
var
ccc:Pchar;
procedimento OpenForm(mainForm:TForm);stdcall;
var
Formulário1: TForm1;
ptr:PLongInt;
começar
ptr:=@(Application.MainForm);
ptr^:=LongInt(mainForm);
Form1:=TForm1.Create(mainForm);
fim;
procedimento InputCCC(Texto: Pchar);stdcall;
começar
ccc := Texto;
fim;
procedimento ShowCCC;stdcall;
começar
ShowMessage(String(ccc));
fim;
exportações
OpenForm;
EntradaCCC,
Mostrar CCC;
começar
fim.
Código fonte do chamador:
unidade Unidade1;
interface
usa
Windows, Mensagens, SysUtils, Classes, Gráficos, Controles, Formulários, Diálogos,
StdCtrls;
tipo
TForm1 = classe(TForm)
Botão1: Botão T;
Botão2: Botão T;
Editar1: TEdit;
procedimento Button1Click(Remetente: TObject);
procedimento Button2Click(Remetente: TObject);
privado
{Declarações privadas}
público
{Declarações públicas}
fim;
var
Formulário1: TForm1;
implementação
{$R *.DFM}
procedimento OpenForm(mainForm:TForm);stdcall;External'project2.dll';
procedimento ShowCCC;stdcall;Externo'project2.dll';
procedimento InputCCC(Texto: Pchar);stdcall;External'project2.dll';
procedimento TForm1.Button1Click(Remetente: TObject);
var
Texto: Pchar;
começar
Texto := Pchar(Edit1.Text);
// OpenForm(Application.MainForm);//Para ajustar MDICHILD
InputCCC(Text);//Para testar se as variáveis globais na DLL são compartilhadas entre vários aplicativos
fim;
procedimento TForm1.Button2Click(Remetente: TObject);
começar
ShowCCC;//Isso mostra que as variáveis globais na DLL do aplicativo WINDOWS de 32 bits também estão no espaço de endereço do aplicativo. O aplicativo de 16 bits pode ser diferente e nenhum experimento foi feito.
fim;