Resumen

En este artículo se describe qué es una biblioteca de vínculos dinámicos (DLL) y los distintos problemas que pueden producirse al utilizar archivos DLL.

A continuación, este artículo describe algunos temas avanzados que se deben considerar al desarrollar las DLL. En la descripción de lo que un archivo DLL, este artículo describe métodos dinámicos de vinculación, las dependencias de DLL, puntos de entrada DLL, exportar funciones de archivos DLL y herramientas para solucionar problemas de DLL.

Este artículo finaliza con una comparación de alto nivel de los archivos DLL a los ensamblados de Microsoft.NET Framework.

INTRODUCCIÓN

Para los sistemas operativos de Microsoft Windows que se enumeran en la sección "Se refiere a", gran parte de la funcionalidad del sistema operativo proporciona bibliotecas de vínculos dinámicos (DLL). Además, al ejecutar un programa en uno de estos sistemas operativos Windows, gran parte de la funcionalidad del programa podrá servida por archivos DLL. Por ejemplo, algunos programas pueden contener muchos módulos diferentes, y cada módulo del programa contenido y distribuido en archivos DLL.

El uso de archivos DLL ayuda a promover el diseño modular de código, la reutilización de código, uso eficaz de la memoria y espacio en disco reducido. Por lo tanto, el sistema operativo y los programas se cargan más rápido, se ejecutan más rápidamente y ocupan menos espacio en el disco del equipo.

Cuando un programa utiliza un archivo DLL, un problema que se denomina dependencia puede provocar que el programa no se ejecute. Cuando un programa utiliza un archivo DLL, se crea una dependencia. Si otro programa sobrescribe y rompe esta dependencia, entonces no es posible ejecutar correctamente el programa original.

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

Más información

¿Qué es un archivo DLL?

Un archivo DLL es una biblioteca que contiene código y datos que pueden utilizarse por varios programas al mismo tiempo. Por ejemplo, en sistemas operativos Windows, el archivo Comdlg32 DLL realiza comunes funciones relacionadas con el cuadro de diálogo. Por lo tanto, cada programa puede utilizar la funcionalidad contenida en este archivo DLL para implementar un cuadro de diálogo Abrir . Esto ayuda a promover la reutilización de código y uso eficaz de la memoria.

Mediante el uso de una DLL, un programa puede ser modularizado en componentes separados. Por ejemplo, un programa de contabilidad podrá venderse por módulo. Cada módulo se puede cargar en el programa principal en tiempo de ejecución si está instalado el módulo. Dado que los módulos son independientes, el tiempo de carga del programa es más rápido y un módulo sólo se carga cuando se solicita esa funcionalidad.

Además, las actualizaciones son fáciles de aplicar a cada módulo sin afectar a otras partes del programa. Por ejemplo, puede que un programa de nóminas, y los tipos impositivos cambian cada año. Cuando estos cambios se aíslan en un archivo DLL, se puede aplicar una actualización sin necesidad de generar o volver a instalar el programa.

La lista siguiente describe algunos de los archivos que se implementan como DLL en sistemas operativos Windows:
  • Archivos de controles ActiveX (.ocx)
    Un ejemplo de un control ActiveX es un control de calendario que le permite seleccionar una fecha en un calendario.
  • Archivos (.cpl) del Panel de control
    Un ejemplo de un archivo .cpl es un elemento que se encuentra en el Panel de Control. Cada elemento es un archivo DLL especializado.
  • Archivos (.drv) del controlador de dispositivo
    Un ejemplo de un controlador de dispositivo es un controlador de impresora que controla la impresión a una impresora.

Ventajas DLL

La lista siguiente describe algunas de las ventajas que se proporcionan cuando un programa utiliza un archivo DLL:
  • Utiliza menos recursos
    Cuando varios programas utilizan la misma biblioteca de funciones, un archivo DLL puede reducir la duplicación de código que se carga en el disco y en memoria física. Esto puede influir en gran medida el rendimiento no sólo el programa que se ejecuta en primer plano, sino también de otros programas que se ejecutan en el sistema operativo Windows.
  • Promueve la arquitectura modular
    Un archivo DLL ayuda a promover el desarrollo de programas modulares. Esto le ayudará a desarrollar programas grandes que requieren varias versiones de idioma o un programa que requiere la arquitectura modular. Un ejemplo de un programa modular es un programa de contabilidad que tiene muchos módulos que se pueden cargar dinámicamente en tiempo de ejecución.
  • Simplifica la instalacion e implementacion
    Cuando una función dentro de un archivo DLL necesita una actualización o una revisión, la distribución y la instalación de la DLL no requiere el programa necesario volver a vincular con el archivo DLL. Además, si varios programas utilizan la misma DLL, los programas múltiples se beneficiarán de la actualización o la revisión. Este problema puede producirse con más frecuencia cuando se utiliza una DLL de terceros que periódicamente se actualiza o fijo.

Dependencias de DLL

Cuando un programa o un archivo DLL utiliza una función DLL en otro archivo DLL, se crea una dependencia. Por lo tanto, el programa ya no es independiente, y el programa puede experimentar problemas si se rompe la dependencia. Por ejemplo, el programa puede no funcionar si se produce una de las siguientes acciones:
  • Una DLL dependiente se actualiza a una nueva versión.
  • Se fija una DLL dependiente.
  • Una DLL dependiente se sobrescribe con una versión anterior.
  • Una DLL dependiente se quita del equipo.
Estas acciones se conocen generalmente como conflictos de DLL. Si no se exige la compatibilidad con versiones anteriores, no puede ejecutar correctamente el programa.

La lista siguiente describen los cambios que se han introducido en Microsoft Windows 2000 y posteriores sistemas operativos de Windows para ayudar a minimizar los problemas de dependencia:
  • Protección de archivos de Windows
    En protección de archivos de Windows, el sistema operativo impide que los archivos DLL se actualiza o elimina un agente no autorizado del sistema. Por lo tanto, cuando un programa de instalación intenta quitar o actualizar un archivo DLL que se define como una DLL del sistema, protección de archivos de Windows buscará una firma digital válida.
  • Archivos DLL privados
    Los DLLs privados le permiten aislar un programa de cambios que se realizan en los archivos DLL compartidos. Los archivos DLL privados utilizan información específica de versión o un archivo .local vacío para imponer la versión de la DLL que es utilizada por el programa. Para utilizar archivos DLL privados, busque los archivos DLL en la carpeta raíz. A continuación, para nuevos programas, agregar información específica de la versión para el archivo DLL. Para los programas antiguos, utilice un archivo .local vacía. Cada método indica el sistema operativo para utilizar los archivos DLL privados que se encuentran en la carpeta raíz.

Herramientas para solucionar problemas de DLL

Varias herramientas están disponibles para ayudarle a solucionar problemas DLL. Las herramientas siguientes son algunas de estas herramientas.

Dependency Walker

La herramienta Dependency Walker puede detectar de forma recursiva todos los archivos DLL dependientes que son utilizados por un programa. Cuando se abre un programa de Dependency Walker, Dependency Walker realiza las siguientes comprobaciones:
  • Dependency Walker busca archivos DLL que faltan.
  • Dependency Walker comprueba si los archivos de programa o archivos DLL que no son válidas.
  • Dependency Walker comprueba que las funciones de importación y funciones de exportación coinciden.
  • Dependency Walker comprueba errores de dependencia circular.
  • Dependency Walker comprueba los módulos que no son válidos porque los módulos son para un sistema operativo diferente.
Mediante el uso de Dependency Walker, puede documentar todas las DLL que utiliza el programa. Esto puede ayudar a evitar y corregir problemas DLL que pueden surgir en el futuro. Cuando se instala Microsoft Visual Studio 6.0, Dependency Walker se encuentra en el directorio siguiente:
unidad\Program Files\Microsoft Visual Studio\Common\Tools

Solver de problema Universal de DLL

La herramienta Solucionador Universal de Problemas de DLL (DUPS) es utilizada para auditar, comparar, documentar y mostrar la información del archivo DLL. La lista siguiente describen las utilidades que componen la herramienta DUPS:
  • Dlister.exe
    Esta utilidad enumera todos los archivos DLL en el equipo y registra la información en un archivo de texto o un archivo de base de datos.
  • Dcomp.exe
    Esta herramienta compara los archivos DLL que se enumeran en dos archivos de texto y genera un tercer archivo de texto que contiene las diferencias.
  • Dtxt2DB.exe
    Esta utilidad carga los archivos de texto que se crean mediante la utilidad Dlister.exe y la utilidad de Dcomp.exe en la base de datos dllHell.
  • DlgDtxt2DB.exe
    Esta utilidad proporciona una versión de interfaz gráfica de usuario de la utilidad Dtxt2DB.exe.
Para obtener más información acerca de la herramienta de duplicados, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:
247957 uso de DUPS.exe para resolver problemas de compatibilidad DLL

Base de datos DLL Help

La base de datos DLL Help le ayuda a encontrar las versiones específicas de archivos DLL instalados por productos de software de Microsoft. Para obtener más información acerca de la base de datos DLL Help, visite el siguiente sitio Web de Microsoft:

Desarrollo de DLL

Esta sección describe los problemas y los requisitos que se deben considerar al desarrollar su propia DLL.

Tipos de archivos DLL

Cuando se carga una DLL en una aplicación, dos métodos de vinculación permiten llamar a las funciones DLL exportadas. Los dos métodos de vinculación son la vinculación dinámica en tiempo de carga y vinculación dinámica en tiempo de ejecución.
Vinculación dinámica en tiempo de carga
En la vinculación dinámica en tiempo de carga, una aplicación realiza llamadas explícitas a funciones DLL exportadas como funciones locales. Para utilizar la vinculación dinámica en tiempo de carga, proporcionar un archivo de encabezado (. h) y un archivo de biblioteca (.lib) de importación al compilar y vincular la aplicación. Al hacerlo, el vinculador proporcionará el sistema con la información que es necesaria para cargar el archivo DLL y resolver las ubicaciones de la función exportadas de DLL en tiempo de carga.
Vinculación dinámica en tiempo de ejecución
En la vinculación dinámica en tiempo de ejecución, una aplicación llama a la función LoadLibrary o la función LoadLibraryEx para cargar la DLL en tiempo de ejecución. Después de que la DLL se carga correctamente, utilice la función de GetProcAddress para obtener la dirección de la función DLL exportada que desea llamar. Cuando se utiliza vinculación dinámica en tiempo de ejecución, no es necesario un archivo de biblioteca de importación.

La lista siguiente describe los criterios de aplicación para la vinculación dinámica en tiempo de carga de uso y cuándo utilizar la vinculación dinámica en tiempo de ejecución:
  • Rendimiento de inicio
    Si es importante el rendimiento de inicio de la aplicación, debe utilizar la vinculación dinámica en tiempo de ejecución.
  • Facilidad de uso
    En la vinculación dinámica en tiempo de carga, las funciones DLL exportadas son como las funciones locales. Esto facilita la llamar a estas funciones.
  • Lógica de la aplicación
    En la vinculación dinámica en tiempo de ejecución, una aplicación puede bifurcarse para cargar módulos diferentes según sea necesario. Esto es importante cuando se desarrollan en varios idiomas.

El punto de entrada DLL

Cuando se crea un archivo DLL, puede especificar opcionalmente una función de punto de entrada. La función de punto de entrada se llama cuando procesos o subprocesos se adhieren a la DLL o desasociado a sí mismos desde el archivo DLL. Puede utilizar la función de punto de entrada para inicializar estructuras de datos o destruir las estructuras de datos según sea necesario por el archivo DLL. Además, si la aplicación es multiproceso, puede utilizar almacenamiento local de subprocesos (TLS) para asignar memoria que es privado para cada subproceso en la función de punto de entrada. El código siguiente es un ejemplo de la función de punto de entrada DLL.
BOOL APIENTRY DllMain(HANDLE hModule,// Handle to DLL module
DWORD ul_reason_for_call,// Reason for calling function
LPVOID lpReserved ) // Reserved
{
switch ( ul_reason_for_call )
{
case DLL_PROCESS_ATTACHED:
// A process is loading the DLL.
break;
case DLL_THREAD_ATTACHED:
// A process is creating a new thread.
break;
case DLL_THREAD_DETACH:
// A thread exits normally.
break;
case DLL_PROCESS_DETACH:
// A process unloads the DLL.
break;
}
return TRUE;
}

Cuando la función de punto de entrada devuelve el valor FALSE , la aplicación no se iniciará si utiliza vinculación dinámica en tiempo de carga. Si utiliza vinculación dinámica en tiempo de ejecución, no se cargará la DLL individual.

La función de punto de entrada sólo debe realizar tareas sencillas de inicialización y no debe llamar a cualquier otra carga de DLL o las funciones de terminación. Por ejemplo, en la función de punto de entrada, usted no debe directa o indirectamente llamar la función LoadLibrary o LoadLibraryEx . Además, no debe llamar la función FreeLibrary cuando el proceso está finalizando.

Nota: En aplicaciones multiproceso, asegúrese de que el acceso a los datos globales de DLL está sincronizado (seguro para subprocesos) para evitar la posible corrupción de datos. Para ello, utilice TLS para proporcionar datos únicos para cada subproceso.

Exportar funciones DLL

Para exportar funciones DLL, puede agregar una palabra clave de función a las funciones DLL exportadas o crear un archivo de definición (.def) de módulo que enumera las funciones DLL exportadas.

Para utilizar una palabra clave function, debe declarar cada función que se va a exportar con la siguiente palabra clave:
__declspec (dllexport)
Para utilizar funciones DLL exportadas en la aplicación, debe declarar cada función que se va a importar con la siguiente palabra clave:
__declspec (dllimport)
Normalmente, se utilizaría un archivo de encabezado que tiene una instrucción definir y una instrucción ifdef para separar la declaración de exportación y la instrucción import.

También puede utilizar un archivo de definición de módulo para declarar funciones DLL exportadas. Cuando se utiliza un archivo de definición de módulo, no es necesario agregar la palabra clave function para las funciones DLL exportadas. En el archivo de definición de módulo, declare la instrucción LIBRARY y la instrucción EXPORTS del archivo DLL. El código siguiente es un ejemplo de un archivo de definición.
// SampleDLL.def//
LIBRARY "sampleDLL"

EXPORTS
HelloWorld

Archivo DLL de ejemplo y aplicación

En Microsoft Visual C++ 6.0, puede crear un archivo DLL seleccionando el tipo de proyecto de Biblioteca de vínculos dinámicos Win32 o el
Tipo de proyecto de MFC AppWizard (dll) .

El código siguiente es un ejemplo de un archivo DLL que se creó en Visual C++ mediante el
Tipo de proyecto de 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
)
{
return TRUE;
}

void HelloWorld()
{
MessageBox( NULL, TEXT("Hello World"), TEXT("In a DLL"), MB_OK);
}

// File: SampleDLL.h//
#ifndef INDLL_H
#define INDLL_H

#ifdef EXPORTING_DLL
extern __declspec(dllexport) void HelloWorld() ;
#else
extern __declspec(dllimport) void HelloWorld() ;
#endif

#endif
El código siguiente es un ejemplo de un proyecto de Aplicación de Win32 que llama a la función exportada del archivo DLL 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 la vinculación dinámica en tiempo de carga, debe vincular la biblioteca de importación SampleDLL.lib que se crea al generar el proyecto SampleDLL.

En vinculación dinámica en tiempo de ejecución, se utiliza código similar al siguiente código para llamar a la SampleDLL.dll exporta la función DLL.
...typedef VOID (*DLLPROC) (LPTSTR);
...
HINSTANCE hinstDLL;
DLLPROC HelloWorld;
BOOL fFreeDLL;

hinstDLL = LoadLibrary("sampleDLL.dll");
if (hinstDLL != NULL)
{
HelloWorld = (DLLPROC) GetProcAddress(hinstDLL, "HelloWorld");
if (HelloWorld != NULL)
(HelloWorld);

fFreeDLL = FreeLibrary(hinstDLL);
}
...

Al compilar y vincular la aplicación SampleDLL, el sistema operativo Windows busca la DLL SampleDLL en las ubicaciones siguientes en este orden:
  1. La carpeta de la aplicación
  2. La carpeta actual
  3. La carpeta de sistema de Windows

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

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

El ensamblado de.NET Framework

Con la introducción de Microsoft .NET y del.NET Framework, la mayoría de los problemas que están asociados con archivos DLL se han eliminado utilizando ensamblados. Un ensamblado es una unidad lógica de funcionalidad que se ejecuta bajo el control de .NET common language runtime (CLR). Un ensamblado existe físicamente como un archivo .dll o como un archivo .exe. Sin embargo, internamente un ensamblado es muy diferente desde un archivo DLL Win32 de Microsoft.

Un archivo de ensamblado contiene un manifiesto de ensamblado, metadatos, código de lenguaje intermedio (MSIL) de Microsoft y otros recursos. El manifiesto del ensamblado contiene los metadatos del ensamblado que proporciona toda la información necesaria para un ensamblado se describen a sí mismas. La siguiente información se incluye en el manifiesto del ensamblado:
  • Nombre del ensamblado
  • Información de versión
  • Información de referencia cultural
  • Información sobre nombre seguro
  • La lista de ensamblados de archivos
  • Información de referencia de tipo
  • Información de ensamblado de referencia y dependientes
No se puede ejecutar directamente el código MSIL que se incluye en el ensamblado. En su lugar, la ejecución de código MSIL se administra a través de CLR. De forma predeterminada, cuando se crea un ensamblado, el ensamblado es privado para la aplicación. Para crear un ensamblado compartido requiere que asignar un nombre seguro al ensamblado y, a continuación, publicar el ensamblado en la caché de ensamblados global.

La lista siguiente describen algunas de las características de los ensamblados en comparación con las características de las DLL de Win32:
  • Autodescriptivos
    Cuando se crea un ensamblado, toda la información que se requiere para ejecutar el ensamblado CLR está contenida en el manifiesto del ensamblado. El manifiesto del ensamblado contiene una lista de los ensamblados dependientes. Por lo tanto, el CLR puede mantener un conjunto coherente de ensamblados que se utilizan en la aplicación. En las DLL de Win32, no puede mantener la coherencia entre un conjunto de DLL que se utilizan en una aplicación cuando utiliza archivos DLL compartidos.
  • Control de versiones
    En un manifiesto de ensamblado, información de versión se registra y exigido por el CLR. Además, las directivas de versión permiten exige el uso específico de la versión. En las DLL de Win32, no se puede aplicar control de versiones por el sistema operativo. En su lugar, debe asegurarse de que los archivos DLL son compatibles con versiones anteriores.
  • Implementación Side-by-side
    Ensamblados admiten implementación side-by-side. Una aplicación puede utilizar una versión de un ensamblado y otra aplicación puede utilizar una versión diferente de un ensamblado. A partir de Windows 2000, se admite la implementación de side-by-side localizando los archivos DLL en la carpeta de la aplicación. Además, la protección de archivos de Windows impide que archivos DLL se sobrescriban o sustituido por un agente no autorizado del sistema.
  • Aislamiento y contención por cuenta propia
    Puede ser una aplicación que se desarrolla utilizando un ensamblado independiente y aislado de otras aplicaciones que se ejecutan en el equipo. Esta característica le ayuda a crear instalaciones de impacto cero.
  • Ejecución
    Un ensamblado se ejecuta bajo los permisos de seguridad que se suministran en el manifiesto del ensamblado y que están controlados por el CLR.
  • Independiente del idioma
    Un ensamblado puede desarrollarse utilizando cualquiera de los lenguajes .NET compatibles. Por ejemplo, puede desarrollar un ensamblado en Microsoft Visual C# y, a continuación, utilizar el ensamblado en un proyecto de Microsoft Visual Basic. NET.

Referencias

Para obtener más información acerca de los archivos DLL y los ensamblados de.NET Framework, visite los siguientes sitios Web de Microsoft:
Conflictos de archivos DLL
http://msdn2.microsoft.com/en-us/library/ms811694.aspx

Implementar el uso compartido de aplicaciones de componentes de side-by-side
http://msdn2.microsoft.com/en-us/library/ms811700.aspx

Cómo generar y servicio aplicaciones aisladas y ensamblados en paralelo para Windows XP
http://msdn2.microsoft.com/en-us/library/ms997620.aspx

Simplificación de la implementación y resolver conflictos de DLL con el.NET Framework
http://msdn2.microsoft.com/en-us/netframework/aa497268.aspx

Guía del desarrollador de.NET Framework: ensamblados
http://msdn2.microsoft.com/en-us/library/hk5f40ct(vs.71).aspx

Vinculación dinámica en tiempo de ejecución
http://msdn2.microsoft.com/en-us/library/ms685090.aspx

Almacenamiento local de subprocesos
http://msdn2.microsoft.com/en-us/library/ms686749.aspx
Propiedades

Id. de artículo: 815065 - Última revisión: 17 feb. 2017 - Revisión: 2

Comentarios