open ld_library_path cannot windows linux dll operating-system shared-libraries

windows - ld_library_path - Arquitectónicamente, ¿cuál es la diferencia entre un objeto compartido(SO) y una biblioteca de enlace dinámico(DLL)?



ld_library_path windows (1)

Una Dll es prácticamente el mismo mecanismo que usan los archivos .so o .dylib (MacOS), por lo que es muy difícil explicar exactamente cuáles son las diferencias.

La diferencia principal está en lo que está visible por defecto de cada tipo de archivo. Los archivos .so exportan la vinculación de nivel de idioma (gcc), lo que significa que (de forma predeterminada) todos los símbolos C y c ++ que son "externos" están disponibles para vincularse cuando se incorporan .so. También significa que, al resolver los archivos .so es esencialmente un paso de enlace, al cargador no le importa de qué archivo .so proviene un símbolo. Simplemente busca los archivos .so especificados en algún orden siguiendo las reglas de paso de enlace habituales a las que se adhieren los archivos .a.

Los archivos DLL, por otro lado, son una característica del sistema operativo, completamente separados del paso del enlace del idioma. MSVC usa archivos .lib para vincular tanto bibliotecas estáticas como dinámicas (cada archivo dll genera un archivo .lib emparejado que se usa para vincular), por lo que el programa resultante está completamente "vinculado" (desde un punto de vista centrado en el idioma) una vez que se construye .

Sin embargo, durante la etapa de enlace, los símbolos se resolvieron en las bibliotecas que representan las Dll, lo que permite al vinculador crear la tabla de importación en el archivo PE que contiene una lista explícita de dll y los puntos de entrada a los que se hace referencia en cada dll. En el momento de la carga, Windows no tiene que realizar un "enlace" para resolver los símbolos de las bibliotecas compartidas: ese paso ya se realizó: el cargador de Windows simplemente carga los archivos DLL y conecta las funciones directamente.

La pregunta está prácticamente en el título: en términos de implementación a nivel de sistema operativo, ¿en qué se diferencian los objetos compartidos y los archivos DLL?

La razón por la que pregunto esto es porque recientemente leí esta página al extender Python, que dice:

Unix y Windows utilizan paradigmas completamente diferentes para la carga de código en tiempo de ejecución. Antes de intentar construir un módulo que pueda cargarse dinámicamente, tenga en cuenta cómo funciona su sistema.

En Unix, un archivo de objeto compartido (.so) contiene el código que utilizará el programa y también los nombres de funciones y datos que espera encontrar en el programa. Cuando el archivo se une al programa, todas las referencias a esas funciones y datos en el código del archivo se cambian para señalar las ubicaciones reales en el programa donde las funciones y los datos se colocan en la memoria. Esto es básicamente una operación de enlace.

En Windows, un archivo de biblioteca de vínculos dinámicos (.dll) no tiene referencias colgantes. En cambio, un acceso a funciones o datos pasa por una tabla de búsqueda. Por lo tanto, el código DLL no tiene que ser reparado en tiempo de ejecución para referirse a la memoria del programa; en su lugar, el código ya utiliza la tabla de búsqueda de la DLL, y la tabla de búsqueda se modifica en el tiempo de ejecución para apuntar a las funciones y los datos.

¿Alguien podría elaborar sobre eso? Específicamente, no estoy seguro de entender la descripción de los objetos compartidos que contienen referencias a lo que esperan encontrar. De manera similar, una DLL suena como el mismo mecanismo para mí.

¿Es esta una explicación completa de lo que está pasando? ¿Hay mejores? ¿Hay de hecho alguna diferencia?

Soy consciente de cómo enlazar a una DLL u objeto compartido y un par de mecanismos (listados .def, dllexport / dllimport) para escribir DLL, así que no estoy buscando explícitamente cómo hacerlo en esas áreas; Estoy más intrigado por lo que está pasando en el fondo.

(Edición: otro punto obvio: soy consciente de que funcionan en diferentes plataformas, usan diferentes tipos de archivos (ELF vs PE), son incompatibles con ABI, etc.)