¿Qué es una DLL? ?

Resumen

Este artículo explica qué es una biblioteca de vínculos dinámicos (DLL) y los diversos problemas que pueden ocurrir al usar una DLL.

A continuación, este artículo explica algunos aspectos avanzados que debes considerar al desarrollar tu propia DLL. Al explicar qué es una DLL, este artículo explica los métodos de vinculación dinámica, las dependencias de DLL, los puntos de entrada de DLL, las funciones de DLL exportadas y las herramientas de solución de problemas de DLL.

Este artículo concluirá con una comparación de alto nivel de DLL y ensamblados de Microsoft .NET Framework.

Introducción

Para los sistemas operativos Microsoft Windows enumerados en la sección "Se aplica a", gran parte de la funcionalidad del sistema operativo la proporcionan bibliotecas de vínculos dinámicos (DLL). Además, cuando ejecuta un programa en uno de estos sistemas operativos Windows, gran parte de la funcionalidad del programa puede ser proporcionada por archivos DLL. Por ejemplo, algunos programas pueden contener muchos módulos diferentes y cada módulo del programa está contenido y distribuido desde una DLL.

El uso de DLL ayuda a promover la modularidad del código, la reutilización del código, el uso eficiente de la memoria y la reducción del uso del espacio en disco. Como resultado, el sistema operativo y los programas se cargan y ejecutan más rápido y ocupan menos espacio en el disco de su computadora.

Cuando un programa utiliza una DLL, un problema llamado dependencia puede impedir que el programa se ejecute. Cuando un programa usa una DLL, se crea una dependencia. Si otro programa sobrescribe y corrompe esa dependencia, es posible que el programa original no se ejecute correctamente.

Con la introducción de Microsoft .NET Framework, la mayoría de los problemas de dependencia se han eliminado mediante el uso de ensamblados.

Más información

¿Qué es una DLL?

Una DLL es una biblioteca que contiene código y datos que pueden ser utilizados por múltiples programas simultáneamente. Por ejemplo, en los sistemas operativos Windows, la DLL Comdlg32 realiza funciones comunes relacionadas con los cuadros de diálogo. Por lo tanto, cada programa puede utilizar la funcionalidad contenida en esta DLL para implementar el cuadro de diálogo Abrir. Esto ayuda a promover la reutilización de código y el uso eficiente de la memoria.

Al utilizar archivos DLL, los programas se pueden modularizar y componer de componentes relativamente independientes. Por ejemplo, un programa de contabilidad podría venderse por módulos. Los módulos individuales se pueden cargar en el programa principal en tiempo de ejecución (si los módulos correspondientes están instalados). Los programas se cargan más rápido porque los módulos son independientes entre sí y los módulos solo se cargan cuando se solicita la funcionalidad correspondiente.

Además, las actualizaciones se pueden aplicar más fácilmente a módulos individuales sin afectar otras partes del programa. Por ejemplo, es posible que tenga un programa de cálculo de nómina en el que las tasas impositivas cambien cada año. Cuando los cambios están aislados en la DLL, puede aplicar la actualización sin reconstruir ni instalar todo el programa.

La siguiente tabla describe algunos de los archivos que se implementan como DLL en el sistema operativo Windows: Archivos de control ActiveX (.ocx)

Un ejemplo de un control ActiveX es el control de calendario. , que le permite seleccionar fechas desde el calendario. Archivos del Panel de control (.cpl)

Un ejemplo de un archivo .cpl es un elemento ubicado en el Panel de control. Cada entrada es una DLL privada. Archivo de controlador de dispositivo (.drv)

Un ejemplo de controlador de dispositivo es un controlador de impresora que controla la impresión en una impresora.

Ventajas de la DLL

La siguiente tabla ilustra algunas de las ventajas que se ofrecen cuando un programa utiliza una DLL: ? Utiliza menos recursos

Cuando varios programas utilizan la misma Cuando se utiliza como biblioteca, una DLL puede reducir la cantidad de duplicación de código cargado en el disco y en la memoria física.

Esto puede afectar en gran medida no sólo a los programas que se ejecutan en primer plano, sino también a otros programas que se ejecutan en el sistema operativo Windows. Promover la arquitectura modular

Las DLL ayudan a promover el desarrollo de programas modulares. Esto puede ayudarle a desarrollar programas grandes que requieren versiones en múltiples idiomas o programas que requieren una arquitectura modular. Un ejemplo de programa modular es un programa de contabilidad que tiene múltiples módulos que se pueden cargar dinámicamente en tiempo de ejecución. Implementación e instalación simplificadas

La implementación e instalación de una DLL no requiere restablecer el enlace del programa a la DLL cuando es necesario actualizar o reparar las funciones de la DLL. Además, si varios programas utilizan la misma DLL, varios programas se beneficiarán de la actualización o solución. Este problema puede ocurrir con más frecuencia cuando utiliza archivos DLL de terceros que se actualizan o reparan periódicamente.

Dependencias de DLL

Las dependencias se crean cuando un programa o DLL utiliza funciones DLL de otra DLL. Por lo tanto, el programa ya no es independiente y, si esta dependencia se corrompe, el programa puede experimentar problemas. Por ejemplo, es posible que el programa no se ejecute si ocurre una de las siguientes situaciones: • Una DLL dependiente se actualiza a una nueva versión. DLL de dependencia fija. La DLL dependiente se sobrescribe con su versión anterior. Las DLL dependientes se eliminaron de la computadora.

Estas operaciones suelen denominarse conflictos de DLL. Si no se aplica la compatibilidad con versiones anteriores, es posible que el programa no se ejecute correctamente.

La siguiente tabla describe los cambios introducidos en Microsoft Windows 2000 y sistemas operativos Windows posteriores para ayudar a minimizar los problemas de dependencia: ? Protección de archivos de Windows

En Protección de archivos de Windows, el sistema operativo previene agentes no autorizados actualicen o eliminen archivos DLL del sistema. Por lo tanto, Protección de archivos de Windows buscará una firma digital válida cuando una operación de instalación de un programa intente eliminar o actualizar una DLL definida como una DLL del sistema. DLL privada

Una DLL privada protege su programa de los cambios realizados en una DLL compartida. Las DLL privadas utilizan información específica de la versión o un archivo .local vacío para imponer la versión de la DLL utilizada por el programa. Para utilizar una DLL privada, busque la DLL en la carpeta raíz del programa. Luego, para programas nuevos, agregue información específica de la versión a la DLL. Para programas más antiguos, utilice un archivo .local vacío. Cada método le dice al sistema operativo que use una DLL privada ubicada en la carpeta raíz del programa.

Herramientas de solución de problemas de DLL

Hay varias herramientas disponibles para ayudarle a solucionar problemas de DLL. A continuación se presentan algunas de estas herramientas.

Dependency Walker

La herramienta Dependency Walker escanea de forma recursiva para encontrar todas las DLL dependientes utilizadas por un programa. Cuando abre un programa en Dependency Walker, Dependency Walker realiza las siguientes comprobaciones: • Dependency Walker comprueba si faltan archivos DLL. Dependency Walker busca archivos de programa o DLL no válidos. Dependency Walker comprueba si las funciones importadas y exportadas coinciden. Dependency Walker comprueba si hay errores de dependencia cíclicos. Dependency Walker comprueba si hay módulos que no son válidos debido a que están dirigidos a un sistema operativo diferente.

Al utilizar Dependency Walker, puede registrar todas las DLL utilizadas por su programa.

Esto puede ayudar a evitar y corregir problemas de DLL que puedan ocurrir en el futuro. Al instalar Microsoft Visual Studio 6.0, Dependency Walker se ubicará en el siguiente directorio: unidad\Archivos de programa\Microsoft Visual Studio\Common\Tools

DLL Universal Problem Solver

DLL Universal Problema La herramienta Solver (DUPS) se utiliza para revisar, comparar, registrar y mostrar información de DLL. La siguiente tabla describe las utilidades que componen la herramienta DUPS: • Dlister.exe

Esta utilidad enumera todas las DLL en la computadora y registra esta información en un archivo de texto o de base de datos. Dcomp.exe

Esta utilidad compara las DLL enumeradas en dos archivos de texto y produce un tercer archivo de texto que contiene las diferencias. Dtxt2DB.exe

Esta utilidad carga archivos de texto creados utilizando la utilidad Dlister.exe y la utilidad Dcomp.exe en la base de datos dllHell. DlgDtxt2DB.exe

Esta utilidad proporciona una versión de interfaz gráfica de usuario (GUI) de la utilidad Dtxt2DB.exe.

Tipos de DLL

Cuando carga una DLL en una aplicación, puede utilizar dos métodos de vinculación para llamar a funciones DLL exportadas. Los dos métodos de vinculación son la vinculación dinámica en tiempo de carga y la vinculación dinámica en tiempo de ejecución.

Enlace dinámico en tiempo de carga

En el enlace dinámico en tiempo de carga, la aplicación realiza llamadas explícitas a funciones DLL exportadas como si fueran funciones nativas. Para utilizar enlaces dinámicos en tiempo de carga, proporcione archivos de encabezado (.h) e importe archivos de biblioteca (.lib) al compilar y vincular su aplicación. Al hacer esto, el vinculador proporciona al sistema la información que necesita para cargar la DLL y resuelve las ubicaciones de las funciones de la DLL exportadas en el momento de la carga.

Enlace dinámico en tiempo de ejecución

En el enlace dinámico en tiempo de ejecución, una aplicación llama a la función LoadLibrary o a la función LoadLibraryEx para cargar una DLL en tiempo de ejecución. Una vez que la DLL se haya cargado correctamente, puede utilizar la función GetProcAddress para obtener la dirección de la función DLL exportada a la que llamar. Cuando se utilizan enlaces dinámicos en tiempo de ejecución, no es necesario utilizar un archivo de biblioteca de importación.

La siguiente lista describe las condiciones de la aplicación con respecto a cuándo usar enlaces dinámicos en tiempo de carga y cuándo usar enlaces dinámicos en tiempo de ejecución: ? Rendimiento de inicio

Si el rendimiento de inicio inicial de la aplicación es importante , se deben utilizar enlaces dinámicos en tiempo de ejecución. Facilidad de uso

En los enlaces dinámicos en tiempo de carga, las funciones DLL exportadas son similares a las funciones nativas. Esto le permite llamar cómodamente a estas funciones. Lógica de la aplicación

En el enlace dinámico en tiempo de ejecución, la aplicación se puede bifurcar para que se carguen diferentes módulos según sea necesario. Esto es importante al desarrollar versiones en varios idiomas.

Punto de entrada de DLL

Al crear una DLL, opcionalmente puede especificar una función de punto de entrada. Las funciones de punto de entrada se llaman cuando procesos o subprocesos se adjuntan o desconectan de una DLL. Puede utilizar funciones de punto de entrada para inicializar o destruir estructuras de datos según lo necesite la DLL. Además, si su aplicación tiene múltiples subprocesos, puede utilizar el almacenamiento local de subprocesos (TLS) en la función de punto de entrada para asignar memoria dedicada a cada subproceso. El siguiente código es un ejemplo de una función de punto de entrada de DLL.

BOOL APIENTRY DllMain(

HANDLE hModule, // Identificador del módulo DLL

DWORD ul_reason_for_call, // Motivo de la llamada a la función

LPVOID lpReserved ) // Reservado

{

interruptor ( ul_reason_for_call )

{

caso DLL_PROCESS_ATTACHED:

// Un proceso está cargando la DLL.

break;

case DLL_THREAD_ATTACHED:

// Un proceso está creando un nuevo hilo.

break;

case DLL_THREAD_DETACH:

// Un hilo sale normalmente.

break

case DLL_PROCESS_DETACH:

// Un proceso descarga la DLL.

break;

}

return TRUE; >

Cuando la función de punto de entrada devuelve un valor FALSO, la aplicación no se inicia si está utilizando enlaces dinámicos en tiempo de carga. Si está utilizando enlaces dinámicos en tiempo de ejecución, solo no se cargarán las DLL individuales.

La función de punto de entrada solo debe realizar tareas de inicialización simples y no debe llamar a ninguna otra función de carga o terminación de DLL. Por ejemplo, dentro de una función de punto de entrada, no debe llamar directa o indirectamente a la función LoadLibrary o a la función LoadLibraryEx. Además, las funciones de FreeLibrary no deben llamarse cuando finaliza el proceso.

Nota: En aplicaciones multiproceso, asegúrese de que el acceso a los datos globales de la DLL esté sincronizado (seguro para subprocesos) para evitar una posible corrupción de datos. Para hacer esto, use TLS para proporcionar datos únicos a cada hilo.

Exportar funciones DLL

Para exportar una función DLL, puede agregar palabras clave de función a la función DLL exportada o puede crear un archivo de definición de módulo (.def) para enumerar las funciones exportadas. Funciones DLL.

Para usar la palabra clave function, debe declarar cada función a exportar usando la siguiente palabra clave: __declspec(dllexport) Para usar una función DLL exportada en una aplicación, debe declararla usando la siguiente palabra clave Funciones individuales para importar: __declspec(dllimport) Normalmente, es mejor utilizar un archivo de encabezado que contenga declaraciones de definición y declaraciones ifdef para separar las declaraciones de exportación y las declaraciones de importación.

También puede utilizar un archivo de definición de módulo para declarar funciones DLL exportadas. Cuando utiliza un archivo de definición de módulo, no es necesario agregar palabras clave de función a las funciones DLL exportadas. En un archivo de definición de módulo, declara la declaración LIBRARY y la declaración EXPORTS de la DLL. El siguiente código es un ejemplo de un archivo de definición.

// SampleDLL.def

//

BIBLIOTECA "sampleDLL"

EXPORTACIONES

HolaMundo

Aplicaciones y DLL de muestra

En Microsoft Visual C 6.0, puede crear una DLL seleccionando el tipo de proyecto "Biblioteca de vínculos dinámicos Win32" o el "Asistente para aplicaciones MFC (dll)".

El siguiente código es un ejemplo de una DLL creada en Visual C utilizando el tipo de proyecto "Biblioteca de vínculos dinámicos Win32".

// SampleDLL.cpp

//

#include "stdafx.h"

#define EXPORTING_DLL

#include "sampleDLL.h"

BOOL APIENTRY DllMain( HANDLE hModule,

DWORD ul_reason_for_call,

LPVOID lpReserved

)

{

devuelve VERDADERO;

}

void HelloWorld()

{

MessageBox( NULL, TEXT("Hola mundo"), TEXT("En una DLL"), MB_OK

}

// Archivo: SampleDLL.h

//

#ifndef INDLL_H

#define INDLL_H

#ifdef EXPORTING_DLL

extern __declspec(dllexport) void HolaMundo() ;

#else

extern __declspec(dllimport) void HolaMundo() ;

#endif

#endif

El siguiente código es un ejemplo de un proyecto de "Aplicación Win32" que llama a la función DLL exportada en la DLL SampleDLL.

// SampleApp.cpp

//

#include "stdafx.h"

#include "sampleDLL.h"

int APIENTRY WinMain(HINSTANCE hInstance,

HINSTANCE hPrevInstance,

LPSTR lpCmdLine,

int nCmdShow)

{

HelloWorld();

return 0;

}

Nota: en los enlaces dinámicos en tiempo de carga, debes vincular La biblioteca de importación SampleDLL.lib se crea al crear el proyecto SampleDLL.

En el enlace dinámico en tiempo de ejecución, debe llamar a la función DLL exportada SampleDLL.dll usando un código similar al siguiente.

...

typedef VOID (*DLLPROC) (LPTSTR);

...

HINSTANCE hinstDLL;

DLLPROC HolaMundo;

BOOL fFreeDLL;

hinstDLL = LoadLibrary("sampleDLL.dll");

if (hinstDLL != NULL)

{

HolaMundo = (DLLPROC) GetProcAddress(hinstDLL, "HolaMundo");

if (HolaMundo != NULL)

( HelloWorld);

fFreeDLL = FreeLibrary(hinstDLL);

}

...

Cuando compila y vincula la aplicación SampleDLL , el sistema operativo Windows buscará la DLL SampleDLL en las siguientes ubicaciones en el siguiente orden: 1. Carpeta de la aplicación

2. Carpeta actual

3. > p>

Nota: La función GetSystemDirectory devuelve la ruta a la carpeta del sistema de Windows.

4. Carpeta de Windows

Nota: La función GetWindowsDirectory devuelve la ruta de la carpeta de Windows.

Ensamblados de .NET Framework

Con la introducción de Microsoft .NET y .NET Framework, la mayoría de los problemas asociados con las DLL se han eliminado mediante el uso de ensamblados. Un ensamblado es una unidad funcional lógica que se ejecuta bajo el control del tiempo de ejecución del lenguaje público (CLR) de .NET. Los ensamblados en realidad existen como archivos .dll o .exe. Sin embargo, internamente, el ensamblaje es bastante diferente al de la DLL de Microsoft Win32.

Los archivos de ensamblado contienen el manifiesto del ensamblador, metadatos de tipo, código de lenguaje intermedio de Microsoft (MSIL) y otros recursos.

El manifiesto del ensamblado contiene metadatos del ensamblado para proporcionar toda la información necesaria para que el ensamblado sea un ensamblado autodescriptivo. El manifiesto del ensamblado contiene la siguiente información: Nombre del ensamblado Información de la versión Información cultural Información de nombre seguro Lista de archivos del ensamblado Información de referencia de tipo Información del ensamblado dependiente y de referencia

El código MSIL contenido en el ensamblado no se puede ejecutar directamente. debe ejecutarse a través del CLR. De forma predeterminada, cuando crea un ensamblado, el ensamblado es específico de la aplicación. Para crear un ensamblado compartido, debe asignar un nombre seguro al ensamblado y luego publicarlo en la caché global de ensamblados.

La siguiente tabla ilustra algunas de las características de un ensamblado y las compara con las características de una DLL Win32: ? Autodescriptivo

Cuando crea un ensamblado, el CLR ejecuta el programa Toda la información necesaria para el montaje está contenida en el manifiesto de montaje. El manifiesto del ensamblado contiene una lista de ensamblados dependientes. Por lo tanto, CLR puede mantener un conjunto coherente de ensamblajes utilizados en las aplicaciones. En las DLL de Win32, cuando se utiliza una DLL compartida, no se puede mantener la coherencia entre un conjunto de DLL utilizados en una aplicación. Control de versiones

En el manifiesto del ensamblado, el CLR registra y aplica la información de la versión. Además, el uso específico de la versión se puede imponer mediante políticas de versión. En las DLL de Win32, el sistema operativo no puede implementar el control de versiones. En su lugar, debe asegurarse de que la DLL sea compatible con versiones anteriores. Implementación paralela

Los ensamblados admiten la implementación paralela. Una aplicación puede usar una versión de un ensamblado, mientras que otra aplicación puede usar una versión diferente del ensamblado. A partir de Windows 2000, se admite la implementación en paralelo colocando la DLL en la carpeta de la aplicación. Además, la Protección de archivos de Windows evita que agentes no autorizados sobrescriban o reemplacen las DLL del sistema. Independientes y aisladas

Las aplicaciones desarrolladas mediante ensamblados pueden ser independientes y aisladas de otras aplicaciones que se ejecutan en la computadora. Esta característica ayuda a crear una instalación sin interrupciones. Ejecución

El ensamblado se ejecuta bajo los permisos de seguridad proporcionados por el manifiesto del ensamblado y controlados por el CLR. Independencia del lenguaje

Los ensamblados se pueden desarrollar utilizando cualquier lenguaje .NET compatible. Por ejemplo, puede desarrollar un ensamblado en Microsoft Visual C# y luego usarlo en un proyecto de Microsoft Visual Basic .NET