Biblioteca de enlaces dinámicos

Una biblioteca de enlaces dinámicos (del idioma inglés , traducida al italiano con biblioteca de enlaces dinámicos ), en informática , indica una biblioteca de software que se carga dinámicamente en tiempo de ejecución, en lugar de estar vinculada estáticamente a un ejecutable en tiempo de compilación . Estas bibliotecas son conocidas por las siglas DLL , que es la extensión del archivo que tienen en el sistema operativo Microsoft Windows , o también con el término bibliotecas compartidas (de shared library , usado en la literatura de sistemas Unix ). En los sistemas que utilizan ELF como formato de archivo ejecutable , como Solaris o Linux , también se conocen como ".so", abreviatura de Shared Object .

Ventajas y desventajas

La separación del código en bibliotecas de enlaces dinámicos le permite dividir el código ejecutable en partes separadas conceptualmente, que se cargarán solo si realmente se necesitan. Además, una sola biblioteca, cargada en la memoria, puede ser utilizada por varios programas, sin necesidad de recargarla, lo que ahorra recursos del sistema. Este método de carga bajo demanda también permite instalaciones parciales de un sistema de software, en el que solo las bibliotecas asociadas con las funciones que el usuario desea utilizar están realmente presentes en la memoria masiva, tal como se seleccionaron durante la fase de instalación.

Otra ventaja es la posibilidad de actualizar un programa modificando solo las DLL: al insertar una versión diferente de la DLL, que contiene correcciones de errores , por ejemplo , todos los programas que la usan se "actualizarán" automáticamente sin necesidad de volver a compilarlos.

La principal desventaja está relacionada con el hecho de que una nueva versión de una DLL podría realizar los llamados cambios importantes , ya sea voluntariamente o, sin saberlo, debido a errores en la nueva versión. Un cambio importante es un cambio crítico en el comportamiento del código de la función que hace que ya no sea compatible con las convenciones en uso (por ejemplo, una función que anteriormente devolvía NULL en caso de un error en los parámetros y que ahora establece errno y devuelve un valor no nulo). Aún más crítico es el caso en el que un instalador sobrescribe una DLL con una versión anterior. Pueden ocurrir otros problemas en el entorno COM . Estos problemas, bien conocidos por los programadores de Windows , se agrupan bajo el nombre de DLL hell .

En algunos sistemas operativos, típicamente Unix y similares a Unix , es posible hacer que coexistan versiones diferentes e incompatibles de la misma biblioteca, siempre que estén presentes individualmente en el sistema de archivos en diferentes rutas y sea posible, al conectar el programa, 'identificación de la versión correcta de la biblioteca a utilizar. De esta forma, los programas vinculados antes de la instalación de la nueva biblioteca pueden seguir utilizando la versión anterior. [1]

Los sistemas operativos tipo Windows mantienen una copia de seguridad de las DLL del sistema en una memoria caché especial , en la carpeta oculta C:\windows\system32\dllcache. C:\windows\system32\dllPor otro lado, las bibliotecas en uso se almacenan en la carpeta .

DLL en Microsoft Windows

Estructura y función

A continuación se describe la estructura y funcionamiento de una biblioteca de enlaces dinámicos en un entorno Windows, sin embargo los conceptos expresados ​​son generalmente equivalentes en todos los sistemas que permiten el uso de bibliotecas dinámicas.

Una biblioteca de enlaces dinámicos es efectivamente un código ejecutable. Cada archivo ejecutable ( EXE o DLL) tiene un punto de entrada invocado por el sistema operativo inmediatamente después de la carga. Para una DLL, el punto de entrada se asigna convencionalmente a la función (de todos modos, a discreción del compilador ). DllMain

La función DllMain, además de cargar la DLL, también se invoca en la descarga o cuando se crea o destruye un hilo en el proceso en el que reside la DLL.

A diferencia de un archivo EXE, la DLL debe salir del punto de entrada tan pronto como haya terminado las inicializaciones necesarias.

Estructura

Para simplificar, se puede pensar en una biblioteca como una colección de funciones. Cada una de estas funciones tendrá su propia dirección base, calculada como un desplazamiento con respecto a la dirección base asignada por el sistema operativo al cargar la librería (ver siguiente párrafo). Lo que distingue a una biblioteca dinámica es que estas funciones se pueden exportar , es decir, sus nombres se colocan en una lista en una sección del ejecutable. Por lo tanto, es posible determinar el punto de entrada de una función con una búsqueda de texto basada en el nombre de la función. Esta operación la realiza la API GetProcAddress que devuelve la dirección de la función cuyo nombre se pasa como parámetro.

Cargando

El sistema operativo carga las bibliotecas dinámicas en el espacio de memoria del proceso que las solicitó. De esta forma, acceder al código de la DLL tendrá un rendimiento casi equivalente al del propio código de la aplicación o al de las bibliotecas estáticas (veremos por qué son casi equivalentes más adelante).

Para evitar que el código de la aplicación y el código de la DLL ocupen la misma ubicación de memoria, el enlazador deberá preparar la DLL para la reubicación . En la práctica, el sistema operativo determina un área de memoria disponible y reasigna cualquier referencia de memoria contenida en el código DLL. Como esto lleva tiempo, cada DLL tiene su propia dirección base ideal : la reubicación solo será necesaria si ya se ha asignado una DLL anterior a esta dirección predeterminada. Para especificar la dirección ideal, puede usar una regla general, basada en la letra inicial del nombre de la DLL, de acuerdo con la siguiente tabla:

Letra inicial Dirección básica
ANTES DE CRISTO 0x60000000
DF 0x61000000
soldado americano 0x62000000
JL 0x63000000
mes 0x64000000
relaciones públicas 0x65000000
EN 0x66000000
VX 0x67000000
YZ 0x68000000

Enlace a un ejecutable

La conexión de un ejecutable a una biblioteca dinámica tiene lugar durante la ejecución (en tiempo de ejecución ) y se realiza a través de la API LoadLibrary, que acepta el nombre de la biblioteca como entrada . Por ejemplo, LoadLibrary(_T("MyLib.dll"))cargará la DLL en el espacio de memoria de la aplicación MyLib.dll.

El vínculo puede ser de dos tipos: explícito o implícito.

Enlace explícito

La conexión explícita es administrada directamente por el código del programa con el uso de las dos API descritas anteriormente LoadLibrary. GetProcAddressSi usa el lenguaje C , asignará un puntero a la función especificada en la que, al usar la función solicitada, cargará la dirección con GetProcAddress. Esta técnica le permite administrar adecuadamente la condición en la que una DLL requerida no está presente en el sistema, pero en general es más engorrosa porque requiere el uso explícito de las dos API. Esta técnica es fundamental cuando se utilizan algunos lenguajes de programación, como por ejemplo Visual Basic .

Enlace implícito

La vinculación implícita es manejada directamente por el vinculador en tiempo de compilación y se usa cuando se supone que una DLL siempre está presente en el sistema. Cada vez que se llama a una función contenida en una DLL en el código fuente, el enlazador vinculará la llamada de función a una función auxiliar , es decir, a una función ficticia. Dentro del ejecutable habrá una tabla que contiene los stubs de todas las funciones DLL requeridas. Al cargar el ejecutable, el sistema operativo cargará automáticamente todas las DLL requeridas y asignará cada código auxiliar al punto de entrada de la función relativa en la DLL relativa. Si no se encuentra una DLL requerida (o incluso una sola función en una DLL), el sistema operativo bloqueará el inicio del programa con un mensaje de error.

El uso de enlaces implícitos tiene una desventaja en términos de rendimiento, porque cada vez que se llama a una función contenida en una DLL se da un doble salto a la función: primero al stub y luego a la dirección de la función; la sobrecarga generada es realmente insignificante.

Enlace implícito retrasado

Una variante del enlace implícito esperado por algunos compiladores es el enlace retrasado . En este caso, se utiliza un código auxiliar especial , que el sistema operativo no asigna a la carga. En cambio, este código auxiliar , la primera vez que se invoca, se asignará automáticamente (con la técnica de conexión explícita) a la función DLL. Esta técnica tiene la ventaja de no requerir la presencia de la DLL para cargar el ejecutable, junto con la conveniencia de no tener que cargar explícitamente la librería desde el código

Notas

  1. ^ Sitio de HP, Manual de Digital Unix: comprobar la carga de la versión de la biblioteca

Artículos relacionados

Enlaces externos