Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 18-11-2009
Robin1 Robin1 is offline
Miembro
 
Registrado: nov 2009
Posts: 14
Poder: 0
Robin1 Va por buen camino
Modo Correcto de Cerrar .Dll

Hola a todos, y un gran saludo.

El tema que me ocupa hoy, es el siguiente.

En días pasados, he estado trabajando en el desarrollo de una Dll (Se trata de un formulario en Delphi 7, con algunos controles WebBrowser, para ser compartido, con una aplicación hecha también en Delphi 7).

De este modo, mi .Dll la he escrito sin inconveniente alguno.

El llamado a la .dll desde el formulario principal, se hace perfectamente, pero he notado esto:

1) Si solo abro la aplicación principal, y trabajo con ella, y luego la cierro, sin haber llamado la Dll, todo va de maravilla.

2) Si abro la aplicación principal, y llamo la .Dll, esta carga, y puedo luego cerrarla, pero, a la hora de cerrar la aplicación principal, inicialmente genera un error en código exadecimal, para luego abrirse una ventana que genera un error 216 en tiempo de ejecución.

Haciendo pruebas, descubri, que si en el evento "OnClose" del Form principal agregaba estas lineas:

Código:
Application.Destroy;
 Exit;
Ya no se generaba dicho error, pero al revisar en el administrador de tareas de Windows, la aplicación sigue corriendo en memoria...

He leído que se trata en algunos casos de un virus, pero en mi caso, he probado en otra de mis máquinas, que recién acababa de formatear, para verificar que no se tratase de un virus.

¿Que puede ser?

Mil gracias por la ayuda, y un gran abrazo

Julián
Responder Con Cita
  #2  
Antiguo 18-11-2009
Avatar de rgstuamigo
rgstuamigo rgstuamigo is offline
Miembro
 
Registrado: jul 2008
Ubicación: Santa Cruz de la Sierra-Bolivia
Posts: 1.646
Poder: 17
rgstuamigo Va por buen camino
Arrow

Bueno pienso que esas lineas de codigo que mencionas son innecesaria..
Por otro lado mira este hilo..
Saludos...
__________________
"Pedid, y se os dará; buscad, y hallaréis; llamad, y se os abrirá." Mt.7:7
Responder Con Cita
  #3  
Antiguo 19-11-2009
gerardus gerardus is offline
Miembro
 
Registrado: dic 2007
Posts: 43
Poder: 0
gerardus Va por buen camino
Si la DLL usa cualquier parte de la VCL (Forms, reports, componentes, etc...) como parece ser que es tu caso, tanto la DLL como la aplicación que la llame tienen que estar enlazadas con la opción "Build with runtime packages". (Compiler | Options | packages | Checkear "Build with runtime packages")
De lo contrario, la aplicación y la DLL tendrán cada una su copia de la VCL, lo que suele dar estos problemas. Algunas variables globales como Application o Screen existen dos veces, etc...
En la lista de packages debes tener todos los packages que van a usar la aplicación y la DLL.
(De hecho, un runtime package no es más que una DLL con algunas funciones de registro propias de Delphi).

Cordialmente,

Gerard.
Responder Con Cita
  #4  
Antiguo 19-11-2009
JosepGA JosepGA is offline
Miembro
 
Registrado: jun 2007
Ubicación: Tarragona
Posts: 166
Poder: 17
JosepGA Va por buen camino
hola,

te pongo un ejemplo resumido del fuente tal y como yo lo hago, mis primeras experiencias con Dlls me llevaron a averiguar que hay dos maneras de cargarlas, con la aplicación al iniciar o por requerimiento, yo lo hago de la segunda manera:

(***** unit FUNCION CARGA DLLS, LA CARGA Y LIBERA DE MEMORIA ******)
Código Delphi [-]

unit FuncionCargaDlls;

interface

Uses
  tGlobales, { Declaración para el Tipo de Variables Globales de la Aplicación en las Dlls }
  Globales, { Variables Globales de la Aplicación }
  AsignacionGlobales,

  SysUtils, StdCtrls, Windows, Forms, Classes, SQLExpr, DBClient, SimpleDS, Controls,

  CRSQLConnection;

Type

  tProcedimientoCargar = Procedure( vGlobales : tVariablesGlobales;
                                    Const tSQLConexionGeneral : tCRSQLConnection ); far;

  EDLLCargaError = Class( Exception );


  Procedure CargarRecursoDllExplicitamente( NombreDll : String;
                                            NombreProcedimiento : String;
                                            Const tSQLConexionGeneral, tSQLConexionGestion, tSQLConexionContabilidad : tCRSQLConnection );

implementation

Procedure CargarRecursoDllExplicitamente( NombreDll : String;
                                          NombreProcedimiento : String;
                                          Const tSQLConexionGeneral : tCRSQLConnection );
Var
  PunteroLibreria : tHandle;
  Procedimiento : tProcedimientoCargar;
Begin
  PunteroLibreria := LoadLibrary( PChar( NombreDll + '.DLL' ) );
  Try
    If PunteroLibreria = 0 Then
      Begin
        Raise EDLLCargaError.Create( 'Imposible Cargar la DLL ' + NombreDll );
      End
    Else
      Begin
        @Procedimiento := GetProcAddress( PunteroLibreria, PChar( NombreProcedimiento ) );
        If ( @Procedimiento = Nil ) Then
          RaiseLastWin32Error
        Else
          Procedimiento( VariablesGlobales,
                         tSQLConexionGeneral );
      End;
  Finally
    FreeLibrary( PunteroLibreria ); { Descarga la Libreria de Memoria }
  End;
End;


(****** APLICACION PRINCIPAL *******)

Código Delphi [-]

unit FuncionCargaDlls;

interface

Uses
  tGlobales, { Declaración para el Tipo de Variables Globales de la Aplicación en las Dlls }
  Globales, { Variables Globales de la Aplicación }
  AsignacionGlobales,

  SysUtils, StdCtrls, Windows, Forms, Classes, SQLExpr, DBClient, SimpleDS, Controls,

  CRSQLConnection;

type
  TFormMenu = class(TForm)
    ..
  private
    ..
  public
    ..

  end;

var
  FormMenu: TFormMenu;

implementation

Uses
  FuncionCargaDlls;

procedure TFormMenu.EjecutarOpcionClick(Sender: TObject);
begin
  CargarRecursoDllExplicitamente( 'DllEdiciones', 'NombreOpcionExportadaEjecutar1',
                                  FormDMMenuPrincipal.tSQLConexionGeneral );
end;

end.



(******** DLL ejecutada - source proyecto *****)

Código Delphi [-]
 
 Library DllEdiciones;

uses
  AsignarConfiguracionAplicacion,
  DeclaracionesOpcionesExportadas;

Exports
  NombreOpcionExportadaEjecutar1,
  NombreOpcionExportadaEjecutar2,
  ..
  NombreOpcionExportadaEjecutarn;

{$R *.RES}

Begin
  AsignarLaConfiguracionDeLasAplicaciones; // Inicializar configuraciones por defecto o lo que sea
End.



(** DLL ejecutada - fuente "DeclaracionesOpcionesExportadas" **)

Código Delphi [-]
  
  unit DeclaracionesOpcionesExportadas;

interface

Uses
  Forms,
  SQLExpr,
  SysUtils,
  CRSQLConnection,
  
  ModuloDatosEdiciones,
  tGlobales,
  Globales,
  AsignacionGlobales,

  FuenteFormularioEjecutar1,
  FuenteFormularioEjecutar2,
  ..
  FuenteFormularioEjecutarn;

procedure NombreOpcionExportadaEjecutar1( vGlobales : tVariablesGlobales; Const tSQLConexionGeneral : tCRSQLConnection ); Far; Export;
procedure NombreOpcionExportadaEjecutar2( vGlobales : tVariablesGlobales; Const tSQLConexionGeneral : tCRSQLConnection ); Far; Export;
..
procedure NombreOpcionExportadaEjecutarn( vGlobales : tVariablesGlobales; Const tSQLConexionGeneral : tCRSQLConnection ); Far; Export;

implementation

procedure NombreOpcionExportadaEjecutar1( vGlobales : tVariablesGlobales; Const tSQLConexionGeneral : tCRSQLConnection ); Far; Export;
Begin
  AsignacionValoresGlobales( vGlobales );

  ActivarConexionesModuloDeDatos( tSQLConexionGeneral );

  Application.CreateForm( tFormFuenteFormularioEjecutar1, FormFuenteFormularioEjecutar1 );
  With FormFuenteFormularioEjecutar1 do
    Try
      ShowModal;
    Finally
      Free;
    End;

  DesactivarConexionesModuloDeDatos( tSQLConexionGeneral );
End;

procedure NombreOpcionExportadaEjecutar2( vGlobales : tVariablesGlobales; Const tSQLConexionGeneral : tCRSQLConnection ); Far; Export;
Begin
  AsignacionValoresGlobales( vGlobales );

  ActivarConexionesModuloDeDatos( tSQLConexionGeneral );

  Application.CreateForm( tFormFuenteFormularioEjecutar2, FormFuenteFormularioEjecutar2 );
  With FormFuenteFormularioEjecutar2 do
    Try
      ShowModal;
    Finally
      Free;
    End;

  DesactivarConexionesModuloDeDatos( tSQLConexionGeneral );
End;

..

procedure NombreOpcionExportadaEjecutarn( vGlobales : tVariablesGlobales; Const tSQLConexionGeneral : tCRSQLConnection ); Far; Export;
Begin
  AsignacionValoresGlobales( vGlobales );

  ActivarConexionesModuloDeDatos( tSQLConexionGeneral );

  Application.CreateForm( tFormFuenteFormularioEjecutarn, FormFuenteFormularioEjecutarn );
  With FormFuenteFormularioEjecutarn do
    Try
      ShowModal;
    Finally
      Free;
    End;

  DesactivarConexionesModuloDeDatos( tSQLConexionGeneral );
End;

end.


Espero que te sea de utilidad

Un saludo
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Uso correcto excepciones duilioisola OOP 4 23-03-2009 09:25:54
...lo justo y lo correcto... Jure Humor 16 17-08-2007 08:43:24
Cerrar conexión al cerrar formulario arantzal Conexión con bases de datos 5 09-08-2006 12:43:52
Modo diseño y modo ejecución buildero_d OOP 3 11-09-2005 06:45:00
DDE , es lo correcto? nicocer Varios 4 31-10-2003 08:09:18


La franja horaria es GMT +2. Ahora son las 10:46:59.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi