¿Qué hay en una DLL y cómo funciona?

86

Siempre hago referencia a las DLL en mi código C #, pero siguen siendo un misterio que me gustaría aclarar. Esta es una especie de volcado de preguntas sobre las DLL.

Entiendo que una DLL es una biblioteca vinculada dinámicamente, lo que significa que otro programa puede acceder a esta biblioteca en tiempo de ejecución para obtener "funcionalidad". Sin embargo, considere el siguiente proyecto ASP.NET con Web.dlly Business.dll( Web.dlles la funcionalidad del front-end y hace referencia Business.dlla tipos y métodos).

  1. En que punto Web.dll se vincula dinámicamente Business.dll? ¿Observa mucho en el disco duro de Windows que se golpea para tareas aparentemente pequeñas cuando usa Word (etc.) y creo que Word se está apagando y vinculando dinámicamente la funcionalidad de otras DLL?

    1a. Además, ¿qué carga y vincula la DLL: el sistema operativo o algún marco de tiempo de ejecución como el marco .NET?

    1b. ¿Cuál es el proceso de "vinculación"? ¿Se realizan comprobaciones de compatibilidad? ¿Cargando en la misma memoria? ¿Qué significa realmente vincular?

  2. ¿Qué ejecuta realmente el código en la DLL? ¿Lo ejecuta el procesador o hay otra etapa de traducción o compilación antes de que el procesador entienda el código dentro de la DLL?

    2a. En el caso de una DLL construida en C # .NET, ¿qué ejecuta esto: el marco .NET o el sistema operativo directamente?

  3. ¿Funciona una DLL de Linux en un sistema Windows (si existe tal cosa), o son específicos del sistema operativo?

  4. ¿Son las DLL específicas de un marco en particular? ¿Puede una DLL construida con C # .NET ser utilizada por una DLL construida con, por ejemplo, Borland C ++?

    4a. Si la respuesta a 4 es "no", ¿cuál es el punto de una DLL? ¿Por qué los distintos marcos no utilizan sus propios formatos para los archivos vinculados? Por ejemplo: un .exe integrado en .NET sabe que un tipo de archivo .abc es algo que puede vincular a su código.

  5. Volviendo a la Web.dll/ Business.dllejemplo - para obtener un tipo de clase de cliente que necesita hacer referencia Business.dlla Web.dll. Esto debe significar que Business.dllcontiene algún tipo de especificación sobre lo que es realmente una clase de cliente. Si hubiera compilado mi Business.dllarchivo en, digamos, Delphi: ¿C # lo entendería y sería capaz de crear una clase de cliente, o hay algún tipo de información de encabezado o algo que dice "oye, lo siento, solo puedes usarme desde otra DLL de Delphi" ?

    5a. Lo mismo se aplica a los métodos; ¿Puedo escribir un CreateInvoice()método en una DLL, compilarlo en C ++ y luego acceder y ejecutarlo desde C #? ¿Qué me detiene o me permite hacer esto?

  6. Sobre el tema del secuestro de DLL, seguramente la DLL de reemplazo (mala) debe contener las firmas y tipos de método exactos como el que está siendo secuestrado. Supongo que esto no sería difícil de hacer si pudiera averiguar qué métodos estaban disponibles en la DLL original.

    6a. ¿Qué en mi programa C # está decidiendo si puedo acceder a otra DLL? Si mi DLL secuestrado contuviera exactamente los mismos métodos y tipos que el original pero fue compilado en otro idioma, ¿funcionaría?

¿Qué es la importación y el registro de DLL?

Remotec
fuente
21
Esta pregunta podría estar pidiendo la respuesta más larga en la historia de SO.
Matti Virkkunen
4
Deberían haber sido 12 preguntas separadas.
Henk Holterman
2
Esta es una pregunta genial, pero estoy realmente de acuerdo con @Chaos y @Matti. Esta pregunta necesita más atención y podría / debería dividirse en varias preguntas diferentes.
Chris Thompson
3
Fue un poco complicado cuando lo escribí + Quería centralizar el conocimiento en un área :)
Remotec
1
Debería ser una wiki comunitaria a estas alturas.
leppie

Respuestas:

74

En primer lugar, debe comprender la diferencia entre dos tipos muy diferentes de DLL. Microsoft decidió utilizar las mismas extensiones de archivo (.exe y .dll) con .NET (código administrado) y código nativo, sin embargo, las DLL de código administrado y las DLL nativas son muy diferentes por dentro.

1) ¿En qué punto web.dll se vincula dinámicamente a business.dll? ¿Observa mucho en Windows HDD thrashing para tareas aparentemente pequeñas cuando usa Word, etc. y creo que esta Word se apaga y se vincula dinámicamente en la funcionalidad de otras DLL?

1) En el caso de .NET, las DLL se cargan generalmente a pedido cuando se ejecuta el primer método que intenta acceder a algo desde la DLL. Es por eso que puede obtener TypeNotFoundExceptions en cualquier lugar de su código si no se puede cargar una DLL. Cuando algo como Word de repente comienza a acceder mucho al HDD, es probable que se esté intercambiando (obteniendo datos que se han intercambiado en el disco para hacer espacio en la RAM)

1a) Además, ¿qué carga y vincula la DLL: el O / S o algún marco de tiempo de ejecución como el marco .Net?

1a) En el caso de las DLL administradas, el marco .NET es lo que se carga, JIT compila (compila el código de bytes .NET en código nativo) y vincula las DLL. En el caso de las DLL nativas, es un componente del sistema operativo que carga y vincula la DLL (no es necesaria una compilación porque las DLL nativas ya contienen código nativo).

1b) ¿Cuál es el proceso de "vinculación"? ¿Se verifica que exista compatibilidad? ¿Cargando en la misma memoria? ¿Qué significa realmente vincular?

1b) La vinculación es cuando las referencias (por ejemplo, llamadas a métodos) en el código de llamada a símbolos (por ejemplo, métodos) en la DLL se reemplazan con las direcciones reales de las cosas en la DLL. Esto es necesario porque las direcciones eventuales de las cosas en la DLL no se pueden conocer antes de que se cargue en la memoria.

2) ¿Qué ejecuta realmente el código en la DLL? ¿Lo ejecuta el procesador o hay otra etapa de traducción o compilación antes de que el procesador entienda el código dentro de la DLL?

2) En Windows, los archivos .exe y .dll son bastante idénticos. Los archivos .exe y .dll nativos contienen código nativo (el mismo material que ejecuta el procesador), por lo que no es necesario traducir. Los archivos .exe y .dll administrados contienen el código de bytes .NET que se compila primero con JIT (traducido al código nativo).

2a) En el caso de una DLL construida desde C # .net, ¿qué está ejecutando esto? ¿El .Net framework o el sistema operativo directamente?

2a) Una vez compilado el código JIT, se ejecuta exactamente de la misma manera que cualquier código.

3) ¿Una DLL de Linux funciona en un sistema Windows (si existe tal cosa) o son específicos del sistema operativo?

3) Las DLL administradas pueden funcionar como están, siempre que los marcos de ambas plataformas estén actualizados y quien haya escrito la DLL no haya roto deliberadamente la compatibilidad mediante el uso de llamadas nativas. Los archivos DLL nativos no funcionarán tal como están, ya que los formatos son diferentes (aunque el código de máquina en el interior es el mismo, si ambos son para la misma plataforma de procesador). Por cierto, en Linux, las "DLL" se conocen como archivos .so (objeto compartido).

4) ¿Son específicos de un marco en particular? ¿Puede una DLL construida con C # .Net ser utilizada por una DLL construida con Borland C ++ (solo ejemplo)?

4) Las DLL administradas son específicas del marco .NET, pero naturalmente funcionan con cualquier lenguaje compatible. Las DLL nativas son compatibles siempre que todos utilicen las mismas convenciones (convenciones de llamada (cómo se pasan los argumentos de función en el nivel de código de máquina), denominación de símbolos, etc.)

5) Volviendo al ejemplo web.dll / business.dll. Para obtener un tipo de clase de cliente, necesito hacer referencia a business.dll desde web.dll. Esto debe significar que business.dll contiene una especificación de algún tipo de lo que realmente es una clase de cliente. Si hubiera compilado mi archivo business.dll, digamos que Delphi lo entendería C # y sería capaz de crear una clase de cliente, o hay algún tipo de información de encabezado o algo que diga "oye, lo siento, solo puedes usarme desde otro dll de Delphi" .

5) Las DLL administradas contienen una descripción completa de cada clase, método, campo, etc. que contienen. AFAIK Delphi no es compatible con .NET, por lo que crearía DLL nativas, que no se pueden usar en .NET directamente. Probablemente podrá llamar a funciones con PInvoke, pero no se encontrarán definiciones de clases. No uso Delphi, así que no sé cómo almacena la información de tipo con DLL. C ++, por ejemplo, se basa en archivos de encabezado (.h) que contienen las declaraciones de tipo y deben distribuirse con la DLL.

6) Sobre el tema del secuestro de DLL, seguramente la DLL de reemplazo (mala) debe contener las firmas de método exactas, tipos como el que está siendo secuestrado. Supongo que esto no sería difícil de hacer si pudiera averiguar qué métodos, etc., estaban disponibles en la DLL original.

6) De hecho, no es difícil si puede cambiar fácilmente la DLL. Se puede usar la firma de código para evitar esto. Para que alguien pueda reemplazar una DLL firmada, tendría que conocer la clave de firma, que mantuvo en secreto.

6a) Una pregunta repetida aquí, pero esto se remonta a lo que en mi programa C # está decidiendo si puedo acceder a otra DLL. Si mi DLL secuestrado contuviera exactamente los mismos métodos y tipos que el original pero fue compilado en otro idioma, ¿funcionaría?

6a) Funcionaría siempre que sea una DLL administrada, hecha con cualquier lenguaje .NET.

  • ¿Qué es la importación de DLL? y registro dll?

"Importar DLL" puede significar muchas cosas, por lo general significa hacer referencia a un archivo DLL y usar cosas en él.

El registro de DLL es algo que se hace en Windows para registrar globalmente archivos DLL como componentes COM para que estén disponibles para cualquier software en el sistema.

Matti Virkkunen
fuente
3
Agregaría al n. ° 4 que .NET puede traducir archivos DLL para que sean compatibles con cualquier programa nativo que comprenda / use COM (Modelo de objeto común). Muy buenas respuestas aunque.
MerickOWA
7

Un archivo .dll contiene código compilado que puede usar en su aplicación.

A veces, la herramienta utilizada para compilar el .dll importa, a veces no. Si puede hacer referencia al .dll en su proyecto, no importa qué herramienta se utilizó para codificar las funciones expuestas del .dll.

La vinculación ocurre en tiempo de ejecución, a diferencia de las bibliotecas vinculadas estáticamente, como sus clases, que se vinculan en tiempo de compilación.

Puede pensar en un .dll como una caja negra que proporciona algo que su aplicación necesita y que no desea escribir usted mismo. Sí, alguien que comprenda la firma del .dll podría crear otro archivo .dll con un código diferente dentro y su aplicación de llamada no podría notar la diferencia.

HTH

Beth
fuente
6

1) ¿En qué punto web.dll se vincula dinámicamente a business.dll? ¿Observa mucho en Windows HDD thrashing para tareas aparentemente pequeñas cuando usa Word, etc. y creo que esta Word se apaga y se vincula dinámicamente en la funcionalidad de otras DLL?

1) Creo que confunde la vinculación con la carga. El enlace es cuando se prueban todos los controles y equilibrios para asegurarse de que lo que se solicita esté disponible. En el momento de la carga, partes de la dll se cargan en la memoria o se intercambian al archivo de paginación. Esta es la actividad de HD que está viendo.

El enlace dinámico es diferente del enlace estático en que, en el enlace estático, todo el código objeto se coloca en el .exe principal en el momento del enlace. Con la vinculación dinámica, el código del objeto se coloca en un archivo separado (el dll) y se carga en un momento diferente del .exe.

La vinculación dinámica puede ser implícita (es decir, la aplicación se vincula con una lib de importación) o explícita (es decir, la aplicación usa LoadLibrary (ex) para cargar la dll).

En el caso implícito, / DELAYLOAD se puede usar para posponer la carga de la dll hasta que la aplicación realmente la necesite. De lo contrario, al menos algunas partes se cargan (se mapean en el espacio de direcciones del proceso) como parte de la iniciación del proceso. El dll también puede solicitar que nunca se descargue mientras el proceso está activo.

COM usa LoadLibrary para cargar dlls COM. Tenga en cuenta que incluso en el caso implícito, el sistema está usando algo similar a LoadLibrary para cargar la dll al inicio del proceso o en el primer uso.

2) ¿Qué ejecuta realmente el código en la DLL? ¿Lo ejecuta el procesador o hay otra etapa de traducción o compilación antes de que el procesador entienda el código dentro de la DLL?

2) Las DLL contienen código objeto como .exes. El formato del archivo dll es casi idéntico al formato de un archivo exe. Escuché que solo hay un bit que es diferente en los encabezados de los dos archivos.

En el caso de una DLL creada a partir de C # .net, .Net Framework la está ejecutando.

3) ¿Una DLL de Linux funciona en un sistema Windows (si existe tal cosa) o son específicos del sistema operativo?

3) Las DLL son específicas de la plataforma.

4) ¿Son específicos de un marco en particular? ¿Puede una DLL construida con C # .Net ser utilizada por una DLL construida con Borland C ++ (solo ejemplo)?

4) Las DLL pueden interoperar con otros frameworks si se tiene especial cuidado o se escribe algún código de pegamento adicional.

Las DLL son muy útiles cuando una empresa vende varios productos que tienen capacidades superpuestas. Por ejemplo, mantengo una dll de i / o de trama que es utilizada por más de 30 productos diferentes en la empresa. Si tiene varios productos instalados, una actualización de la dll puede actualizar todos los productos a nuevos formatos ráster.

5) Volviendo al ejemplo web.dll / business.dll. Para obtener un tipo de clase de cliente, necesito hacer referencia a business.dll desde web.dll. Esto debe significar que business.dll contiene una especificación de algún tipo de lo que realmente es una clase de cliente. Si hubiera compilado mi archivo business.dll, digamos que Delphi lo entendería C # y sería capaz de crear una clase de cliente, o hay algún tipo de información de encabezado o algo que diga "oye, lo siento, solo puedes usarme desde otro dll de Delphi" .

5) Dependiendo de la plataforma, las capacidades de un dll se presentan de varias formas, a través de archivos .h, archivos .tlb u otras formas en .net.

6) Sobre el tema del secuestro de DLL, seguramente la DLL de reemplazo (mala) debe contener las firmas de método exactas, tipos como el que está siendo secuestrado. Supongo que esto no sería difícil de hacer si pudiera averiguar qué métodos, etc., estaban disponibles en la DLL original.

6) dumpbin / exportaciones y dumbin / importaciones son herramientas interesantes para usar en .exe y .dlls

edgman
fuente
3) DLL son específicas de la plataforma
Henk Holterman