Ver Mensaje Individual
  #10  
Antiguo 24-01-2013
Avatar de nlsgarcia
[nlsgarcia] nlsgarcia is offline
Miembro Premium
 
Registrado: feb 2007
Ubicación: Caracas, Venezuela
Posts: 2.206
Reputación: 21
nlsgarcia Tiene un aura espectacularnlsgarcia Tiene un aura espectacular
cd.rafael,

Cita:
Empezado por cd.rafael
Respecto a la respuesta de nlsgarcia, tu apunte funciona perfecto, pero el tema es que quisiera que fuera de manera dinámica para evitar el crecimiento del tamaño del ejecutable.
Revisa este código:
Código Delphi [-]
library Project1dll;

uses
  SysUtils,
  Classes,
  DllForm in 'DllForm.pas' {frmDllForm};

procedure ShowDllForm;stdcall;
begin
  frmDllForm :=TfrmDllForm.Create(nil);
  frmDllForm.Show;
end;

function ShowDllFormModal:integer;stdcall;
begin
  frmDllForm :=TfrmDllForm.Create(nil);
  Result := frmDllForm.ShowModal;
end;

Exports
    ShowDllForm,
    ShowDllFormModal ;

begin
end.
El código anterior declara una DLL que exporta dos rutinas que visualizan formularios, una en forma Modal (Function) y otra en forma No Modal (Procedure).

Revisa este código:
Código Delphi [-]
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, Db, DBTables;

type
  TShowForm = procedure;
  TShowFormModal = function :integer;

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
  private
    { Private declarations }
    DLLHandle: THandle;
    ShowForm : TShowForm;
    ShowFormModal : TShowFormModal;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowFormModal;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  ShowForm;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
 DLLHandle := LoadLibrary('Project1dll.dll');
 if DLLHandle <> 0 then
 begin
   @ShowForm := GetProcAddress(DLLHandle, 'ShowDllForm');
   @ShowFormModal := GetProcAddress(DLLHandle, 'ShowDllFormModal');
 end;
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
  FreeLibrary(DLLHandle);
end;

end.
El código anterior permite de forma dinámica cargar el Procedure ShowForm y la Function ShowFormModal del DLL anterior para el manejo de formularios.

Cita:
Empezado por cd.rafael
Pude resolver el problema colocando "SimpleShareMem" en el "uses" de la librería (tiene que estar de primero)
Revisa este texto sobre ShareMem:
Cita:
Important note about DLL memory management: ShareMem must be the first unit in your library's USES clause AND your project's (select View-Project 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 DELPHIMM.DLL shared memory manager, which must be deployed along with your DLL. To avoid using DELPHIMM.DLL, pass string information using PChar or ShortString parameters.
Te sugiero que uses parámetros de llamada y respuesta de tipo PChar en vez de Strings con el uso de la DLL lo cual eliminara la necesidad de la Unidad ShareMem y hara el DLL más portable al usar tipos de datos en Windows comunes entre diferentes lenguajes.

Cita:
Empezado por cd.rafael
Ya logré realizar el cargue de la librería más de una vez. Se debe eliminar la instrucción "FreeLibrary" del mismo procedure donde se llama, hay que buscar otra forma para liberarla, tratando de detectar si la forma ya se cerró
En el código anterior se resuelve el problema de la Persistencia del Formulario al manejar la carga y la liberación de memoria de la DLL por separado, esto permite cargar solo las funciones y métodos exportados que sean requeridos y liberarlos al finalizar la aplicación, lo cual es lógico en este caso particular.

Cita:
Empezado por cd.rafael
Cuando se lanza por primera vez la dll, la cual maneja los datos de una tabla X, funciona perfectamente. Cuando se llama la dll por segunda vez para manejar los datos de la tabla Y, sin haber terminado la primera llamada, la primera instancia que estaba manejando la tabla X, adopta los datos de la tabla Y que se maneja en la segunda instancia
Te sugiero revisar la lógica de tu aplicación, quizás estés utilizando variables globales comunes entre llamadas.

Cita:
Empezado por cd.rafael
Lo único que me queda es pasar de librería a un ejecutable para no perder el trabajo.
Revisa todo lo comentado anteriormente, quizás puedas adaptarlo a tu proyecto fácilmente e implementar una DLL portable gestionada de forma dinámica por tu aplicación.

Revisa estos links:
Cita:
Tutorials - Adding forms to a DLL
http://www.delphi-central.com/formdll.aspx

Tutorial - Dynamically Loading DLL's
http://www.delphi-central.com/dynamicdll.aspx
En estos links se explica el manejo de forms en Delphi por medio de DLLs de forma Dinámica y Estática con los ejemplos mostrado anteriormente los cuales se pueden descargar para su análisis.

Espero sea útil

Nelson.

Última edición por nlsgarcia fecha: 24-01-2013 a las 17:31:27.
Responder Con Cita