Problema ao carregar dll em runtime

Delphi

07/06/2005

Bom dia, pessoal.

Dei uma procurada no histórico de mensagens mas não encontrei resposta ao meu problema.

Seguinte: construí uma dll para impressão de notas fiscais de nossos clientes, sendo que cada um tem a sua. Tentei carregar ela somente no momento em que será utilizada, mas não funciona.
Eu passo prá ela a Connection e as notas a serem impressas. Na dll tenho um dataModule que serve unica e exclusivamente pra criação das querys (tbém em run time). Mas na hora de criar as querys, ao passar a Connection para ela, dá pau de violação de acesso. Estou passando a Connection por referência para o DataModule, mas já tentei por valor e tbém não deu.
O mais estranho é que se eu carrego a dll ao abrir a aplicação não dá pau.

Alguém sabe me dizer como posso fazer?

Muito obrigado.

__________________
Marcelo Schmidt


Schmidt

Schmidt

Curtidas 0

Respostas

Carlosfim

Carlosfim

07/06/2005

Marcelo,

Vc está usando a Unit ShareMem do Delphi?

Quando vc precisa passar parâmetros ou receber retornos de funções armazenadas em Dll que não sejam declarados com os tipos nativos do Windows vc precisa usar ShareMem tanto no Aplicativo quanto na Dll. Esta deve ser declarada na Unit do projeto, e deve ser a primeira.


Espero ter ajudado


GOSTEI 0
Schmidt

Schmidt

07/06/2005

Olá Carlos.

Obrigado pela dica, rapaz, mas ainda assim não funcionou. Testei em uma aplicação com um único form e botão que simplesmente chama a dll em questão com o ShareMem no topo dos uses do .dpr. Prá esse funcionou. Agora, pra aplicação onde ele é prá funcionar de verdade, não consigo de jeito nenhum... e é sempre no mesmo lugar: na hora de passar a TADOConnection prá TADOQuery.

Muito obrigado, Carlos, mas se não for pedir demais, tens mais alguma sugestão?

__________________
Marcelo Schmidt


GOSTEI 0
Carlosfim

Carlosfim

07/06/2005

Não, amigo, não tenho nenhuma outra idéia.

Só vendo o código mesmo.


GOSTEI 0
Schmidt

Schmidt

07/06/2005

Olá Carlos, tudo bem?

Bem, vou tentar postar o código aqui.

Esse é o código da função que eu exporto da dll
procedure imprimir(var con: TADOConnection; inicio: integer; fim: integer = 0); safecall; export;
var
  impressao: TImpressaoFMate;
begin

  dtmDados:= TdtmDados.Create(Application);
  dtmDados.setConexao(con);

  impressao:= TImpressaoFMate.criar();
  impressao.imprimir(inicio, fim);
  impressao.destruir();

  dtmDados.Destroy;
  
end;


OK?, bom, o setConexao é um setter normal que recebe o parâmetro e o atribui a uma variável privada, com uma única diferença: o parãmetro é passado por referência.
No mais , tá tranquilo.

Vamos para a parte de criação da query:

constructor TEnderecoMdl.criar();
begin
  inherited create();
  Fqry:= TADOQuery.Create(dtmDados);
  Fqry.Connection:= dtmDados.getConexao;
end;


Esse é o construtor de uma classe da dll. Como se vê, eu crio a qry dinamicamente, o que acontece normalmente. Mas quando a terceira linha do construtor é executada, dá pau que nem adianta colocar aqui, pq não diz nada. diz só que houveram muitas exceções. Debugando a dll, descobri que parece que ela distorce o objeto TADOConnection, pq a descrição não tem nada a ver com isso.

Lembrando: eu coloquei a ShareMem nos dpr dos dois projetos, tanto na aplicação quanto na dll.

Qualquer coisa eu agradeço..

__________________
Marcelo Schmidt


GOSTEI 0
Massuda

Massuda

07/06/2005

Uma sugestão (talvez não funcione)...

Compile tanto seu programa como sua DLL usando packages (Project|Options|Packages|Build with runtime packages), incluindo apenas os packages do Delphi; por exemplo, se for Delphi 5, esses packages seriam Vcl50, Vclx50, Vcldb50, Vclbde50, vcldbx50.

A VCL utiliza algumas variáveis globais internas para controlar forms e datamodules. Quando você cria um programa + DLLs que não compartilham as mesmas variáveis globais costuma dar problema.


GOSTEI 0
Carlosfim

Carlosfim

07/06/2005

Cara, não sei se vai adiantarno seu caso, mas uma sugestão é trocar a diretiva safecall por stdcall.

Já tive problemas de estouro de memória usando safecall e quando troquei para stdcall o problema foi resolvido, porém eu utilizava a dll em questão estaticamente.

Vale apena tentar!!!


GOSTEI 0
POSTAR