FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
|
Herramientas | Buscar en Tema | Desplegado |
#1
|
|||
|
|||
error en dll con una form
Cordial saludo,
He revisado muchos temas respecto al manejo de forms dentro de una dll y hasta ahora no he podido resolver mi problema, que a continuación expongo: Tengo un ejecutable normal el cual invoca a una dll que a su vez lanza una form. Si dicha form la muestro con "ShowModal" todo funciona bien, pero si la dejo solo como "Show", el ejecutable deja de responder. Este es el código que uso en el ejecutable: Código:
procedure TForm1.Button1Click(Sender: TObject); type TDLLFunc = procedure(pStUsuario: String; pStPassword: String; pStDB: String; pStEsquema: String; pStTabla: String); const DLLFunc: TDLLFunc = nil; var DLLHandle: THandle; begin DLLHandle := LoadLibrary('forma.dll'); if (DLLHandle < HINSTANCE_ERROR) then raise Exception.Create('Librería no encontrada.' + SysErrorMessage(GetLastError)); try @DLLFunc := GetProcAddress(DLLHandle, 'pFormaMaestro'); if Assigned(DLLFunc) then DLLFunc(txtUsuario.Text, txtContra.Text, txtBD.Text, txtEsquema.Text, txtTabla.Text); finally FreeLibrary(DLLHandle); end; end; Código:
library forma; uses ShareMem, SysUtils, Dialogs, Windows, Classes, DConexion in 'DConexion.pas' {dtmConexion: TDataModule} , FPrincipal in 'FPrincipal.pas' {frmPrincipal} , FAcerca in 'FAcerca.pas' {frmAcerca} , FBusqueda in 'FBusqueda.pas' {frmBusqueda} , FSplash in 'FSplash.pas' {frmSplash} , FRegistro in 'FRegistro.pas' {frmRegistro}; procedure pFormaMaestro(pStUsuario: String; pStPassword: String; pStDB: String; pStEsquema: String; pStTabla: String); begin //Pantalla Inicial frmSplash := TfrmSplash.Create(nil); frmSplash.Show; frmSplash.Update; //Crear el DataModulo dtmConexion := TdtmConexion.Create(nil); dtmConexion.gStTabla := pStTabla; dtmConexion.gStUsuario := pStUsuario; dtmConexion.gStPassword := pStPassword; dtmConexion.gStDB := pStDB; dtmConexion.gStEsquema := pStEsquema; dtmConexion.pInicioDatos; frmSplash.Hide; frmSplash.Free; //Crear la Forma if (dtmConexion.gBlSelect) then begin try frmPrincipal := TfrmPrincipal.Create(nil); frmPrincipal.ShowModal; dtmConexion.cdsPrincipal.Close; dtmConexion.qryPrincipal.Close; frmPrincipal.Hide; frmPrincipal.Free; except on E: Exception do begin ShowMessage(E.Message); end; end; end; end; exports pFormaMaestro; begin end. Cabe anotar que estas líneas de código: Código:
dtmConexion.cdsPrincipal.Close; dtmConexion.qryPrincipal.Close; frmPrincipal.Hide; frmPrincipal.Free; Agradezco de antemano cualquier colaboración. |
#2
|
||||
|
||||
cd.rafael,
Cita:
El código anterior declara una DLL (DLLForm) que Exporta el Procedure ShowForm el cual muestra un formulario con el método Show declarado en la unidad UnitFrmDLL.pas Revisa el código de la Unidad UnitFrmDLL del DLL anterior. Este formulario es instanciado en el Procedure ShowForm Exportado en el DLL anterior. Revisa este código: El código anterior declara una referencia al procedure ShowForm del DLL anterior e invoca una llamada al mismo. Revisa estos links: Cita:
Espero sea útil Nelson. Última edición por nlsgarcia fecha: 23-01-2013 a las 02:40:22. |
#3
|
||||
|
||||
Hola, cd.rafael.
A ver, lo primero son consejillo. Cuando crees y liberes objetos, yo me aseguraría de que se liberen siempre, haya habido errores o no en el código intermedio. Lo haría de la siguiente manera:
Por otra parte, sobre este código:
Lo primero de lo que me doy cuenta es que el DataModule no lo liberas nunca, a veces las llamadas a dll dan problemas por cosas así. Por otra parte, yo he tenido problemas usando formularios y componentes de base de datos en dll, pero sólo con dbexpres. Y no he sido capaz de arreglarlo, es dbexpres es así
__________________
La Madurez se llama... ~~~Gaia~~~ |
#4
|
|||
|
|||
Cordial Saludo,
De antemano agradezco sus prontas respuestas. 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. La idea es usar esa dll con el fin de evitar casi 20 formas que son similares. Para la otra respuesta de ozsWizzard, te comento que ya había probado el liberar el DataModulo, pero me generaba excepciones que no pude controlarlas. Lo más extraño es que si lo hago de manera estática, como propone nlsGarcia, no me genera error. El problema es cuando es dinámica. Voy a tratar de hacer una forma sencilla sin datamodulo y sin componentes, para ver qué puede ser. Voy comentando lo que me vaya pasando... |
#5
|
|||
|
|||
Cordial Saludo,
Pude resolver el problema colocando "SimpleShareMem" en el "uses" de la librería (tiene que estar de primero). El asunto es que cuando llamo al form con Show, la librería sigue su ejecución y no espera a que el formulario interactúe con el usuario. La verdad no sé porqué puede ser. Lo que necesito es que la librería no termine su ejecución hasta que el formulario se cierre, pero no quiero usar ShowModal, porque me bloquea la aplicación principal. Agradezco toda la colaboración que me puedan prestar. |
#6
|
|||
|
|||
Cordial Saludo,
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 fin... la gran decepción que tuve fue lo siguiente: 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. Puede que sea por el manejo compartido de direcciones de memoria. Lo único que me queda es pasar de librería a un ejecutable para no perder el trabajo. Si de pronto alguien tiene alguna sugerencia, con gusto será escuchada. Gracias. |
#7
|
||||
|
||||
Yo haría funciones distintas para cada tabla. Si no es eso creo que no he entendido bien cual es el problema.
__________________
La Madurez se llama... ~~~Gaia~~~ |
#8
|
|||
|
|||
Cordial Saludo,
La idea de la librería es proporcionar una forma que me permita manejar las operaciones básicas en una tabla cualquiera (insertar, modificar, eliminar, imprimir y exportar). De esta manera evito tener una forma para cada tabla (aclarando que son tablas básicas, de referencia), ya que puedo enviarle a la dll cualquier tabla sin necesidad de generar código específico para cada tabla. Lo más importante es que se cargara de forma dinámica y no incrementar el tamaño del ejecutable principal. Si el requerimiento hubiera permitido mantener la forma en estado modal, no habría problema, pero se necesita poder ver abrir más de una vez dicha librería y es ahí donde todo se complica, porque no independiza los datos. No coloco una función para cada tabla porque no sería algo estándar. Gracias. |
#9
|
||||
|
||||
No estoy seguro, pero cada llamada debería ser independiente.
Lo que yo haría y que, a priori, debería funcionar es lo siguiente: 1.- En la dll, conexión deshabilitada y componentes de base de datos deshabilitados. 2.- La función de la dll tiene que tener como parámetros los datos de conexión y la tabla a la que acceder. 3.- una vez se llama con estos parámetros, la función de la dll debe montar la conexión y el acceso a la tabla. Hasta donde yo sé, no debería haber problema.
__________________
La Madurez se llama... ~~~Gaia~~~ |
#10
|
|||||||
|
|||||||
cd.rafael,
Cita:
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: 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:
Cita:
Cita:
Cita:
Cita:
Revisa estos links: Cita:
Espero sea útil Nelson. Última edición por nlsgarcia fecha: 24-01-2013 a las 17:31:27. |
#11
|
|||
|
|||
Cordial Saludo,
Ya correjí el tema del ShareMem usando PChar, pero el problema de los datos cuando se inician dos instancias de la dll continúa. Las variables que uso para el llamado no son globales, son idnependientes para cada llamada a la dll. Muchas gracias. |
#12
|
||||
|
||||
cd.rafael,
Cita:
Cita:
Cita:
Modifica la DLL forma en lo referente al Data Modulo dtmConexion: La idea es que se cree una nueva variable local del Data Modulo dtmConexion y su instancia correspondiente en cada llamada del Procedimiento pFormaMaestro y que esta libere todos su recursos al finalizar el procedimiento mencionado para de esta forma asegurar que las instancias sean independientes entre llamadas. Espero sea útil Nelson. |
|
|
Temas Similares | ||||
Tema | Autor | Foro | Respuestas | Último mensaje |
Error al crear un MDI Form | jafera | OOP | 6 | 19-07-2011 14:10:13 |
Error con AdoQuery y 2 Form | Cecilio | Conexión con bases de datos | 2 | 23-10-2008 17:37:04 |
Error al crear MDI Form | Faust | Varios | 8 | 23-04-2008 05:12:01 |
Error en form de login | FGarcia | Varios | 2 | 05-02-2006 05:00:27 |
Error Creating Form | RolphyReyes | Varios | 4 | 02-09-2005 19:56:42 |
|