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' ;
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
DLLHandle: THandle;
ShowForm : TShowForm;
ShowFormModal : TShowFormModal;
public
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:
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.