El vinculador MSVC puede vincular archivos de objetos (.obj) y bibliotecas de objetos (.lib) para producir un .EXE o un .DLL.
Para vincular con una DLL, el proceso en MSVC es usar una llamada biblioteca de importación (.LIB) que actúa como un pegamento entre los nombres de las funciones de C y la tabla de exportación de la DLL (en una DLL, una función se puede exportar por nombre o por ordinal:este último se usaba a menudo para API no documentadas).
Sin embargo, en la mayoría de los casos, la tabla de exportación de DLL tiene todos los nombres de funciones y, por lo tanto, la biblioteca de importación (.LIB) contiene información bastante redundante ("importar función ABC -> exportar función ABC ", etc).
Incluso es posible generar un .LIB a partir de un .DLL existente.
Los enlazadores en otras plataformas no tienen esta "característica" y pueden enlazar con bibliotecas dinámicas directamente.
En Linux, el enlazador (no el enlazador dinámico) busca en las bibliotecas compartidas especificadas en el momento del enlace y crea referencias a ellas dentro del ejecutable. Cuando el enlazador dinámico carga estos ejecutables, carga las bibliotecas compartidas que requieren en la memoria y resuelve los símbolos, lo que permite que se ejecuten los archivos binarios.
MySo.a
, si se crea, en realidad incluiría los símbolos que se vincularán directamente en el binario en lugar de las "tablas de búsqueda de símbolos" que se usan en Windows.
La respuesta de rustyx explica el proceso en Windows más a fondo que yo; Ha pasado mucho tiempo desde que usé Windows.
La diferencia que está viendo es más un detalle de implementación:bajo el capó, tanto Linux como Windows funcionan de manera similar:el código llama a una función de código auxiliar que está vinculada estáticamente en su ejecutable y este código auxiliar carga DLL / shlib si es necesario (en caso de retraso cargando, de lo contrario, la biblioteca se carga cuando se inicia el programa) y (en la primera llamada) resuelve el símbolo a través de GetProcAddress
/dlsym
.
La única diferencia es que en Linux estas funciones auxiliares (que se denominan auxiliares PLT) se generan dinámicamente cuando vincula su aplicación con la biblioteca dinámica (la biblioteca contiene suficiente información para generarlos), mientras que en Windows se generan cuando se crea el archivo DLL, en un .lib
separado archivo.
Los dos enfoques son tan similares que en realidad es posible imitar las bibliotecas de importación de Windows en Linux (consulte el proyecto Implib.so).