Fórum Erro ao usar DLL #344231
08/08/2007
0
Pessoal tenho a seguinte dll:
library Biblio;
{ Important note about DLL memory management: ShareMem must be the
first unit in your library´s USES clause AND your project´s (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, Grids, DBGrids, Buttons, StdCtrls, Mask, DBCtrls, ExtCtrls,
ActnList, ComCtrls, FMTBcd, Provider, DBClient;
{$R *.res}
procedure LimpaCampos(vForm: TForm; vFormHandle: THandle);
var i : Integer;
begin
for i := 0 to (vForm.ControlCount -1) do
if vForm.Controls[i].ClassName = ´TEdit´ then
begin
TEdit(vForm.Controls[i]).Text:=´´;
end;
for i := 0 to (vForm.ControlCount -1) do
if vForm.Controls[i].ClassName = ´TDBEdit´ then
begin
TDBEdit(vForm.Controls[i]).Text:=´´;
end;
for i := 0 to (vForm.ControlCount -1) do
if vForm.Controls[i].ClassName = ´TCheckBox´ then
begin
TCheckBox(vForm.Controls[i]).Checked:= False;
end;
for i := 0 to (vForm.ControlCount -1) do
if vForm.Controls[i].ClassName = ´TDBCheckBox´ then
begin
TDBCheckBox(vForm.Controls[i]).Checked:= False;
end;
end;
Exports
LimpaCampos;
begin
end.
E no Form frmCadKits declaro a procedure e a dll.
...
public
{ Public declarations }
end;
procedure LimpaCampos(vForm: TForm; vFormHandle: THandle); external ´biblio.dll´;
var
...
E faço uma chamada no show do Form
procedure TfrmCadKits.FormShow(Sender: TObject);
begin
LimpaCampos(frmCadKits,frmCadKits.Handle);
end;
E recebo o erro:
Project Aplicativo.exe raised exception class EAccessViolation with message ´Access violation at address 045DF5B in module Aplicativo.exe´. Read of address 00000180´. Process stopped. Use Step or Run to continue.
Alguém tem uma solução, já tentei de várias formas e nada, sempre dá esse erro. No mesmo diretório da aplicação estão a biblio.dll e a borlndmm.dll.
Grato a todos.
Alexandre.
Alexandregois
Curtir tópico
+ 0Posts
08/08/2007
Massuda
Gostei + 0
08/08/2007
Emerson Nascimento
[i:1fd0d20f93]{ Important note about DLL memory management: ShareMem must be the
first unit in your library´s USES clause AND your project´s (select
Project-View Source) USES clause [b:1fd0d20f93]if your DLL exports any procedures or
functions that pass strings as parameters or function results[/b:1fd0d20f93]. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }
[/i:1fd0d20f93]
[color=blue:1fd0d20f93]tradução livre:[/color:1fd0d20f93]
[i:1fd0d20f93]{ Nota importante sobre gerenciamento de memória em DLL: ShareMem deve
ser a primeira unit na cláusula USES da sua biblioteca e na cláusula
USES do seu projeto (selecione Project-View Source) se sua DLL exporta
procedimentos que passam strings como parâmetro ou retorno de função.
Isto aplica-se a todas as strings passadas para e da sua DLL -- até
aquelas dentro de registros e classes. ShareMem é a unit com a interface
para o gerenciador de memória compartilhada BORLNDMM.DLL, que deve ser
distribuído junto com sua DLL. Para evitar o uso da BORLNDMM.DLL,
passe as informações string usando parâmetros PChar ou ShortString. }[/i:1fd0d20f93]
[b:1fd0d20f93]teste com este código:[/b:1fd0d20f93]
library Biblio;
{ Important note about DLL memory management: ShareMem must be the
first unit in your library´s USES clause AND your project´s (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, Grids, DBGrids, Buttons, StdCtrls, Mask, DBCtrls, ExtCtrls,
ActnList, ComCtrls, FMTBcd, Provider, DBClient;
{$R *.res}
procedure LimpaCampos(vForm: TForm; vFormHandle: THandle);
var
i : Integer;
classe: string;
begin
// alterei, de forma a fazer a verredura apenas uma vez.
// da forma que estava, se seu formulário tivesse 500
// componentes, a sua dll iria avaliar 2.000 iterações,
// pois faria uma varredura completa 4 vezes.
// da forma que está agora essa varredura será feita apenas
// 1 vez, aumentando a performace
for i := 0 to (vForm.ControlCount -1) do
begin
classe := UpperCase(vForm.Controls[i].ClassName);
if classe = ´TEDIT´ then
TEdit(vForm.Controls[i]).Text := ´´
else
if classe = ´TDBEDIT´ then
TDBEdit(vForm.Controls[i]).Text := ´´
else
if classe = ´TCHECKBOX´ then
TCheckBox(vForm.Controls[i]).Checked := False
else
if classe = ´TDBCHECKBOX´ then
TDBCheckBox(vForm.Controls[i]).Checked := False;
end;
end;
exports
LimpaCampos;
begin
end.
e execute a função como no exemplo abaixo:
procedure TfrmCadKits.FormShow(Sender: TObject); begin LimpaCampos(Self, Self.Handle); end;
Gostei + 0
08/08/2007
Massuda
Note que o tratamento feito no edits que tem no form consiste em atribuir uma string vazia à propriedade Text; indiretamente, está retornando uma string vazia para o executável que está usando a DLL.
Gostei + 0
08/08/2007
Emerson Nascimento
mas posso estar errado....
obs.: os testes que eu fiz funcionaram perfeitamente sem precisar adicionar ShareMem
Gostei + 0
08/08/2007
Massuda
procedure TfrmCadKits.FormShow(Sender: TObject); begin LimpaCampos(Self, Self.Handle); end;
Com relação ao ShareMem, acredito que neste caso deveria incluí-la no uses. Se tiver tempo, dou uma investigada nisso.
Gostei + 0
08/08/2007
Emerson Nascimento
até porque, em função de como o form foi instanciado, a variável frmCadKits pode não ter sido atribuída.
um caso em que isso pode acontecer é se o form foi criado assim:
Application.CreateForm(TfrmCadKits, frmCadastraKits)
no caso, apesar de ser uma instância de TfrmCadKits, a variável ´criada´ será frmCadastraKits e não frmCadKits. o uso de Self evita esse tipo de problema.
:D
Gostei + 0
09/08/2007
Alexandregois
Alexandre.
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)