2011-01-11 8 views
5

Estoy moviendo algunas funciones a una DLL compartida (quiero tener algunas llamadas como un enlace de Windows).código de finalización de delphi en una DLL

Las funciones reales se encuentran actualmente en un unit, y resulta que tienen algunos initialization y algunos finalization código.

Al principio estaba pensando en hacer una transformación directa de unit a library. Así que moví el código initialization entre los principales begin y end.. Pero luego me di cuenta de que no tenía lugar para mover el código finalization. Debo crear y registrar un punto de entrada DLL especial, en su lugar.

Mi pregunta es. ¿Puedo dejar el unit con todas las funciones y los códigos initialization y finalization y simplemente crear un talón library que uses la unidad? ¿se llamará el finalization?

Respuesta

8

El código en las secciones de inicialización de las unidades en la DLL se ejecutará cuando la DLL se cargue por primera vez en el proceso. Las secciones de finalización se activan cuando el archivo DLL se descarga del proceso.

Eugene tiene razón en que puede tener un control más detallado utilizando DLLProc, pero esto solo suele ser necesario para los recursos por subproceso, p. hilo de almacenamiento local.

Me gustaría señalar que existen serias limitaciones en lo que se puede hacer durante DLLMain que es en última instancia donde estas secciones de inicialización/finalización se originan cuando están dentro de una biblioteca. La documentación de MSDN básicamente dice que puede hacer algunas cosas, pero que no hay una lista de comportamiento aceptable. Lo más cerca que se puede encontrar es decir que puede llamar a funciones en kernel32. ¡De lo contrario, todas las apuestas están apagadas!

Hay muchos artículos en la web que describen el problema, pero más allá del tema de MSDN para DLLMain que he vinculado anteriormente, recomendaría leer el Best Practices for Creating DLLs de Microsoft.

El consejo útil que MSDN ofrece es que la biblioteca puede exigir que sus usuarios invoquen una función de inicialización antes de usar la DLL. Se llamaría una función de finalización correspondiente una vez que haya terminado con la DLL. El uso de comctl32.dll adopta este modismo, ver InitCommonControlsEx.

En mi propio código prefiero un enfoque alternativo. Las secciones de inicialización de todas mis unidades registran los métodos de inicialización y finalización. Luego, en la primera llamada a cualquier función exportada de mi biblioteca, se ejecutan los métodos de inicialización, en el orden en que se registraron.Esto no es un problema para mí implementar porque ya estoy controlando todos los puntos de entrada/salida a mi biblioteca.

Me doy cuenta de que esto es más de lo que pedía, pero puede que le resulte útil evitar algunos problemas difíciles de depurar.

+2

+1. En resumen, se llamará al código en una sección de finalización *, pero debido al bloqueo del cargador del sistema operativo, es posible que no lo desee. Evite un posible punto muerto: exporte funciones de inicialización y finalización explícitas para que el proceso de host llame. –

+0

The Old New Thing explica por qué: http://blogs.msdn.com/b/oldnewthing/archive/2004/01/27/63401.aspx –

+2

@Jeroen Iba a vincular a ese artículo, pero eso es un poco el huevo de un comisario y los artículos que relaciona a Raymond parecen haber sido comidos por MS link rot. La mejor referencia que he encontrado es http://www.microsoft.com/whdc/driver/kernel/DLL_bestprac.mspx –

4

Se llamará a la inicialización de una unidad si es un programa y si es una biblioteca.

Lo mismo para la finalización.

Así que sí, puede dejar la unidad tal como está y exportar la funcionalidad requerida.

0

Sugiero que implemente un DLLMain y maneje diferentes situaciones (proceso adjuntar, conexión de hilo, etc.) llamando a procedimientos/funciones dedicados para cada situación. Luego puede llamar a los procedimientos/funciones necesarios desde la inicialización y finalización, si necesita cambiar de DLL a unidad. La razón es que es posible que necesite algún control de grano fino cuando el archivo DLL se adjunta/desconecta a/desde el hilo (que sucederá cuando se establece un enlace de todo el sistema).

+0

No deberías, y The Old New Thing explica por qué: http://blogs.msdn.com/b/oldnewthing/archive/2004/01/27/63401.aspx –

+0

@Jeroen this is all words. De hecho, al implementar ganchos para todo el sistema (y escribí muchos de ellos) en muchos casos necesita usar DLLMain y rastrear el archivo adjunto. Esto se debe a la naturaleza de los ganchos de todo el sistema. –

0

Esto también me pasó a mí. Descubrí que tenía una unidad, esa sección de inicialización que creaba un hilo o hacía algunas cosas, cuando el dll estaba registrado.

He eliminado esta sección de inicialización, y funcionó bien.

Puesto que, se requiere la inicialización de la aplicación .exe, pero no a la aplicación de DLL, hay una bandera variable en la utilidad de sistema, llamado ModuleIsLib acaba de hacer:

initialization 

if not ModuleIsLib then 
begin 
// initialization stuff for .exe file 
end; 

Esto se puede hacer también para sección de finalización también.

Espero que haya ayudado ..!

Cuestiones relacionadas