PDA

Ver la Versión Completa : Pluggins con delphi


GustavoMurias
08-10-2010, 02:32:30
Hola gente, no encontré un hilo relacionado con el uso de dlls así que me lanzo a consultar en uno nuevo...

estoy trabajando en una aplicación MDI que se conecta a traves de un puerto serie a varios dispositivos de adquisición, cada uno con una dirección diferente. ningún problema con esto.

Para ver éstas terminales hice una interfaz gráfica dentro de una dll, que se carga en un MDIChild creado al clickear en un botón, en ese momento le asigno algunos parámetros llamando a un procedimiento exportado, al que le paso como argumento un record. el trabajo del procedimiento (dentro de la dll) es solo tomar el argumento y copiarlo en una variable global del mismo tipo, definida dentro de la dll.

El asunto que no puedo resolver es que cuando abro mas de una ventana y le paso el parámetro, se modifica la variable global en todas las ventanas hijas que haya abiertas, y por lo tanto no consigo la dependencia una ventana-una termianl.

les comento lo que hice: en la dll, dentro de la unit correspondiente al form que se mostrarà:


// declaro como una función el Form que se va a exportar

TMainFormClass = class of TMainController;
function MainFormClass: TFormClass; stdcall; export;

// declaro un procedimiento para modificar la variable y una funcion para leerla

procedure SetDvcProperties(DeviceProperties: TDvcProperties); stdcall; export;
function GetDvcProperties: TDvcProperties; stdcall; export;

// las variables globales

EditingDvc : TDvcProperties;
MainDvcDescriptor : TMainDvcDescriptor;

// luego implemento el procedimiento

procedure SetDvcProperties(DeviceProperties: TDvcProperties); stdcall;
begin
EditingDvc:= DeviceProperties;
end;

y luego en el documento library los exporto

exports MainFormClass;
exports SetDvcProperties;
exports GetDvcProperties;


Transcribo el procedimiento completo del programa principal, desde donde se llama a la dll y se coloca el form en la ventana hija

procedure THardwareLink.OpenGUI(Net, Addr: byte);
type
TMainFormClass = function: TFormClass; stdcall;
var
lMainFormClass: TMainFormClass;
Dvc: TDvcProperties;
GUIModule : string;
Wdw: byte;
begin
Wdw:= HardwareGUIOpen(Net, Addr);
if Wdw = 255 then
begin
Dvc:= FilesModule.ReadDvcProperties(Net, Addr);
GUIModule:= Dvc.GUIFile + '.dll';
FLibHandle:= LoadLibrary(PChar(GUIModule));
HardwareModule:= THardwareModule.Create(Application);

HardwareModule.Caption:= '[' + IntToStr(Dvc.Network) + '.' +
IntToStr(Dvc.Address) + '] ' +
Dvc.ZoneName + ' - ' + Dvc.PlantName;

HardwareModuleUnit.SetDvcProperties(Dvc);

lMainFormClass := GetProcAddress(FLibHandle, 'MainFormClass');
if @lMainFormClass <> nil then
begin // Create a TMainForm instance (not visible)
FLoadedForm := lMainFormClass.Create(nil); // Place the Panel from TMyForm in Panel1
FLoadedForm.Controls[0].Parent := HardwareModule.Panel1;
HardwareModule.ClientWidth:= FLoadedForm.ClientWidth;
HardwareModule.ClientHeight:= FLoadedForm.ClientHeight;
SetDvcProperties(Dvc); // acá le paso el record
end;
HardwareModule.Show;
end
else
Main.MDIChildren[Wdw].BringToFront;
end;

toda la parte que carga el form de la dll en el panel de mi form hija la tomé de un foro y funcionó bien, aunque no se a ciencia cierta que es lo que hace.

espero no haberme excedido demasiado, intento ser explícito para que resulte mas facil la solución.

muchas gracias,

Gustavo.

Ñuño Martínez
13-10-2010, 09:42:56
(...) aunque no se a ciencia cierta que es lo que hace. (...)

Supongo que ya lo sabes, pero creo que el problema está perfectamente descrito en esta frase.

Evidentemente, si cambias una variable global, pues cambia la variable global "en todas las ventanas", como dices. Precisamente eso son las variables globales. Deberías utilizar una propiedad o una variable privada en lugar de la global. Si no entiendes la diferencia entre una "variable global" y una "propiedad privada", quizá debas leerte algún libro de programación, como "La Cara Oculta de Delphi".

GustavoMurias
17-11-2010, 01:47:38
Gracias Ñuño por responder, estuve un tiempo dedicado al hard y ahora estoy volviendo con esta parte.

Le di muchas vueltas al asunto pero aún no consigo lo que quiero, que lo describo aqui abajo:

quiero que cada formulario MDIChild que esté abierto y que haya "cargago" su parte gráfica de una dll (que puede estar o no repetida entre varias forms), pueda recibir el contenido de una variable.

el contenido de la variable es específico para cada instancia de la dll que tengo abierta, para que cada ventana contenga datos diferentes aunque sean de la misma apariencia (cada form responde a una placa específica)

otra restriccion es que, dentro de la dll la variable debe ser global para poder utilizarla desde varios de sus procedimientos y funciones.

Denrto de la dll modifico la variable llamando a un procedimiento desde el programa principal, al que le paso como argumento una variable del mismo tipo.

Hice varias pruebas tratando de limitar el ámbito de la variable en la dll pero no funcionó.
no se me ocurre nada mas...

si se entiende el planteo y alguien tiene alguna idea.. Bienvenida!!

gracias,

gustavo

maeyanes
17-11-2010, 19:22:22
Hola...

Es que tu problema radica precisamente en la variable global...

Lo que tendrías que hacer en determinado momento es declarar alguna variable o propiedad privada o ya de plano pasar la información por medio de parámetros a las funciones y procedimientos...


Saludos...

GustavoMurias
19-11-2010, 02:02:02
Hola maeyanes,

estuve intentando con la variable declarada dentro de private, y tambien pasándola como argumento a un procedimiento. Para esto tuve que quitar el procedimiento exportado del archivo library y colocarlo dentro de la unit del form contenido en la dll, pero de las dos maneras me da un error al ejecutarlo. Read of address xxxx.

Gracias por su ayuda,

Gustavo.