De esta presentaciónel objetivoes — que todos aprendan a crear y usar bibliotecas estáticas y dinámicas, conozcan la diferencia entre bibliotecas estáticas y dinámicas y sepan cómo elegir al usarlas. Aquí no se profundiza en el formato subyacente, el diseño de memoria, etc. de las bibliotecas estáticas y dinámicas. A los interesados, se recomienda un libro: "Autorreflexión del programador: enlace, carga y bibliotecas".
1. Qué es una biblioteca
Una biblioteca es código existente, maduro y reutilizable que ya está escrito.En la práctica, cada programa depende de muchas bibliotecas subyacentes básicas; es imposible que el código de cada persona comience desde cero, por lo tanto, la existencia de las bibliotecas tiene un significado extraordinario.。
En esencia, una biblioteca es una forma binaria de código ejecutable que puede ser cargada en memoria por el sistema operativo para su ejecución. Hay dos tipos de bibliotecas: estáticas (.a, .lib) y dinámicas (.so, .dll).
Lo de estática y dinámica se refiere al enlazado. Repasemos los pasos para compilar un programa hasta convertirlo en un ejecutable:
Figura: Proceso de compilación
2. Biblioteca estática
Se llama "biblioteca estática" porque en la etapa de enlazado, los archivos objeto .o generados por el ensamblador se enlazan y empaquetan junto con las bibliotecas referenciadas dentro del archivo ejecutable. Por lo tanto, el método de enlazado correspondiente se denomina enlace estático.
Imaginemos: una biblioteca estática se enlaza junto con los archivos objeto generados por el ensamblador para formar un ejecutable, por lo que la biblioteca estática debe tener un formato similar al de los archivos .o. De hecho, una biblioteca estática puede considerarse simplemente comoun conjunto de archivos objeto (.o/.objarchivos) que forman una colección, es decir, un archivo formado por muchos archivos objeto comprimidos y empaquetados. Resumen de las características de las bibliotecas estáticas:
- El enlazado de la biblioteca estática con las funciones se realiza en el momento de la compilación.
- En tiempo de ejecución, el programa ya no tiene relación con la biblioteca de funciones, lo que facilita la portabilidad.
- Se desperdician espacio y recursos, porque todos los archivos objeto relacionados y las bibliotecas de funciones implicadas se enlazan y combinan en un solo archivo ejecutable.
A continuación, escribiremos algunas clases simples de C++ para operaciones aritméticas básicas, las compilaremos como una biblioteca estática para que otros las usen. El archivo de cabecera es el siguiente:
| Archivo de cabecera StaticMath.h |
#pragma once
class StaticMath
{
public:
StaticMath(void);
~StaticMath(void);
static double add(double a, double b);//加法
static double sub(double a, double b);//减法
static double mul(double a, double b);//乘法
static double div(double a, double b);//除法
void print();
};
|
En Linux se usaarla herramienta, y en Windows con VS se usalib.exepara comprimir los archivos objeto juntos, numerarlos e indexarlos, a fin de facilitar la búsqueda y la recuperación. Generalmente, los pasos para crear una biblioteca estática se muestran en la figura:
Figura: Proceso de creación de una biblioteca estática
2.1. Creación y uso de bibliotecas estáticas en Linux
2.1.1. Reglas de nomenclatura de bibliotecas estáticas en Linux
La convención de nomenclatura para bibliotecas estáticas en Linux debe ser "lib[your_library_name].a": "lib" es el prefijo, en el medio va el nombre de la biblioteca estática, y la extensión es .a.
2.1.2. Creación de una biblioteca estática (.a)
A través del proceso anterior se puede saber que el procedimiento para crear una biblioteca estática en Linux es el siguiente:
- Primero, compilar el archivo de código a un archivo objeto .o (StaticMath.o)
g++ -c StaticMath.cpp
Tenga en cuenta el parámetro -c; de lo contrario, se compilará directamente como un archivo ejecutable.
- Luego, mediante la herramienta ar, empaquetar el archivo objeto en un archivo de biblioteca estática .a
ar -crv libstaticmath.a StaticMath.o
Generar la biblioteca estáticalibstaticmath.a。
Los proyectos más grandes suelen escribir archivos makefile (CMake y otras herramientas de gestión de proyectos) para generar la biblioteca estática, ya que introducir múltiples comandos es demasiado engorroso.
2.1.3. Uso de la biblioteca estática
Escribir el código de prueba que utilice la biblioteca estática creada anteriormente:
| Código de prueba: |
#include "StaticMath.h"
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
double a = 10;
double b = 2;
cout << "a + b = " << StaticMath::add(a, b) << endl;
cout << "a - b = " << StaticMath::sub(a, b) << endl;
cout << "a * b = " << StaticMath::mul(a, b) << endl;
cout << "a / b = " << StaticMath::div(a, b) << endl;
StaticMath sm;
sm.print();
system("pause");
return 0;
}
|
Para usar una biblioteca estática en Linux, solo es necesario, al compilar, especificar la ruta de búsqueda de la biblioteca estática (opción -L) y especificar el nombre de la biblioteca estática (no se necesitan el prefijo lib ni el sufijo .a, opción -l).
# g++ TestStaticLibrary.cpp -L../StaticLibrary -lstaticmath
- -L: indica el directorio donde se encuentra la biblioteca a enlazar.
- -l: especifica la biblioteca dinámica necesaria al enlazar. El compilador tiene reglas de nomenclatura implícitas al buscar bibliotecas de enlace dinámico: antepone "lib" al nombre dado y añade ".a" o ".so" al final para determinar el nombre de la biblioteca.
2.2. Creación y uso de bibliotecas estáticas en Windows
2.2.1. Creación de una biblioteca estática (.lib)
Si se usa la línea de comandos de VS para generar la biblioteca estática, también se divide en dos pasos para generar el programa:
- Primero, mediante el uso de la opción del compilador/cdeCl.execompilar el código (cl /c StaticMath.cpp), crear el archivo objeto llamado "StaticMath.obj".
- Luego, usar el administrador de bibliotecasLib.exepara enlazar el código (lib StaticMath.obj) y crear la biblioteca estática StaticMath.lib.
Por supuesto, normalmente no hacemos esto; es más conveniente usar la configuración del proyecto de VS. Al crear un programa de consola Win32, marque el tipo de biblioteca estática; abra el "Panel de propiedades" del proyecto -- "Propiedades de configuración" -- "General", y seleccione "Biblioteca estática" como tipo de configuración.
Figura: Configuración de propiedades del proyecto de biblioteca estática en VS
Al compilar (Build) el proyecto se generará la biblioteca estática.
2.2.2. Uso de la biblioteca estática
El código de prueba es el mismo que en Linux. Hay 3 métodos de uso:
Método 1:
Método para usar una biblioteca estática en VS:
- En el proyecto, "Panel de propiedades" -- "Propiedades comunes" -- "Marcos y referencias" -- "Agregar referencia", se mostrará el cuadro de diálogo "Agregar referencia". La pestaña "Proyectos" enumera los proyectos de la solución actual y todas las bibliotecas que se pueden referenciar. En la pestaña "Proyectos", seleccione StaticLibrary. Haga clic en "Aceptar".
- Agregar el directorio del archivo de cabecera StaticMath.h; debe modificar la ruta del directorio de inclusión. Abra el "Panel de propiedades" del proyecto -- "Propiedades de configuración" -- "C/C++" -- "General", y en el valor de propiedad "Directorios de inclusión adicionales", escriba la ruta del directorio donde se encuentra el archivo de cabecera StaticMath.h o navegue hasta ese directorio.
Compile y ejecute OK.
Figura: Resultado de la prueba de la biblioteca estática (VS)
Si la biblioteca estática referenciada no es un subproyecto de la misma solución, sino que se usa una biblioteca estática .lib y archivos de cabecera proporcionados por un tercero, el método anterior no se puede configurar. Los otros 2 métodos de configuración son viables.
Método 2:
Abra el "Panel de propiedades" del proyecto -- "Propiedades de configuración" -- "Enlazador" -- "Línea de comandos", e introduzca la ruta completa de la biblioteca estática.
Método 3:
- "Panel de propiedades" -- "Propiedades de configuración" -- "Enlazador" -- "General", en "Directorios de bibliotecas adicionales" introduzca el directorio donde se encuentra la biblioteca estática;
- "Panel de propiedades" -- "Propiedades de configuración" -- "Enlazador" -- "Entrada", en "Dependencias adicionales" introduzca el nombre de la biblioteca estática StaticLibrary.lib.
3. Biblioteca dinámica
A través de la introducción anterior, se descubre que la biblioteca estática es fácil de usar y entender, y también logra el propósito de reutilización de código. Entonces, ¿por qué se necesitan también bibliotecas dinámicas?
3.1. ¿Por qué se necesitan también bibliotecas dinámicas?
Por qué se necesitan bibliotecas dinámicas se debe, en realidad, a las características de las bibliotecas estáticas.
- El desperdicio de espacio es un problema de las bibliotecas estáticas.
- Otro problema es que las bibliotecas estáticas causan inconvenientes en la actualización, implementación y publicación de programas. Si la biblioteca estática liba.lib se actualiza, todas las aplicaciones que la usan deben recompilarse y publicarse para los usuarios (para los jugadores, puede ser un cambio muy pequeño, pero provoca que todo el programa se descargue de nuevo,actualización completa)。
Las bibliotecas dinámicas no se enlazan al código objeto durante la compilación del programa, sino que se cargan solo cuando el programa se ejecuta.Si diferentes aplicaciones llaman a la misma biblioteca, solo se necesita una instancia de esa biblioteca compartida en la memoria., lo que evita el problema del desperdicio de espacio. Como las bibliotecas dinámicas se cargan solo cuando el programa se ejecuta, también se resuelven los inconvenientes que las bibliotecas estáticas causan en la actualización, implementación y publicación de programas. Los usuarios solo necesitan actualizar la biblioteca dinámica,actualización incremental。
Resumen de las características de las bibliotecas dinámicas:
- La biblioteca dinámica aplaza la carga y el enlazado de algunas funciones de biblioteca hasta el período de ejecución del programa.
- Permite compartir recursos entre procesos. (Por eso las bibliotecas dinámicas también se denominan bibliotecas compartidas).
- Hace que la actualización de algunos programas sea sencilla.
- Incluso se puede lograr que la carga y el enlazado sean controlados completamente por el programador en el código del programa (llamada explícita)。
Windows y Linux tienen formatos de archivo ejecutable diferentes, por lo que hay algunas diferencias al crear bibliotecas dinámicas.
- En el sistema Windows, el formato de archivo ejecutable es el formato PE, y la biblioteca dinámica necesita unLa función DllMain sirve como punto de entrada de inicialización; normalmente, al declarar funciones exportadas, se necesita _declspec(dllexport).Palabra clave。
- Bajo Linux, los archivos ejecutables compilados con gcc tienen por defecto el formato ELF,no requieren un punto de entrada de inicialización, ni tampoco declaraciones especiales para las funciones,por lo que resulta más conveniente escribirlos.
A diferencia de la creación de bibliotecas estáticas, no se necesitan herramientas de empaquetado (ar, lib.exe); basta con usar el compilador para crear una biblioteca dinámica.
3.2. Creación y uso de bibliotecas dinámicas en Linux
3.2.1. Reglas de nomenclatura de las bibliotecas dinámicas en Linux
El nombre de la biblioteca de enlace dinámico tiene la forma libxxx.so; el prefijo es "lib" y el sufijo es ".so".
- Para el archivo de biblioteca real, cada biblioteca compartida tiene un nombre especial llamado "soname". Después de que el programa se inicia, este usa ese nombre para indicar al cargador dinámico qué biblioteca compartida debe cargar.
- En el sistema de archivos, soname es solo un enlace a la biblioteca dinámica real. Para las bibliotecas dinámicas, cada biblioteca también tiene otro nombre para que lo use el compilador. Es un archivo de enlace que apunta al archivo de imagen de la biblioteca real (lib+soname+.so).
3.2.2. Creación de bibliotecas dinámicas (.so)
Escribir el código de la biblioteca dinámica de operaciones aritméticas básicas:
| Archivo de cabecera DynamicMath.h |
#pragma once
class DynamicMath
{
public:
DynamicMath(void);
~DynamicMath(void);
static double add(double a, double b);//加法
static double sub(double a, double b);//减法
static double mul(double a, double b);//乘法
static double div(double a, double b);//除法
void print();
};
|
- Primero, generar el archivo objeto; en este paso se debe añadir la opción del compilador -fpic
g++ -fPIC -c DynamicMath.cpp
-fPIC crea código compilado independiente de la dirección (pic, position independent code), para poder compartirlo entre múltiples aplicaciones.
- Luego, generar la biblioteca dinámica; en este paso se debe añadir la opción del enlazador -shared
g++ -shared -o libdynmath.so DynamicMath.o
-shared especifica la generación de una biblioteca de enlace dinámico.
En realidad, los dos pasos anteriores se pueden combinar en un solo comando:
g++ -fPIC -shared -o libdynmath.so DynamicMath.cpp
3.2.3. Uso de bibliotecas dinámicas
Escribir el código de prueba que usa la biblioteca dinámica:
| Código de prueba: |
#include "../DynamicLibrary/DynamicMath.h"
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
double a = 10;
double b = 2;
cout << "a + b = " << DynamicMath::add(a, b) << endl;
cout << "a - b = " << DynamicMath::sub(a, b) << endl;
cout << "a * b = " << DynamicMath::mul(a, b) << endl;
cout << "a / b = " << DynamicMath::div(a, b) << endl;
DynamicMath dyn;
dyn.print();
return 0;
}
|
Enlazar la biblioteca dinámica para compilar el archivo ejecutable (igual que con la biblioteca estática):
g++ TestDynamicLibrary.cpp -L../DynamicLibrary -ldynmath
Luego ejecutar: ./a.out, ¡¡¡y resulta que da un error!!!
Quizá todos piensen que es porque la biblioteca dinámica y el programa de prueba no están en el mismo directorio; comprobemos si es así:
¡¡¡Se descubre que sigue dando error!!! Entonces, ¿cómo se localiza el archivo de biblioteca compartida durante la ejecución?
1) Cuando el sistema carga el código ejecutable, sabe el nombre de la biblioteca de la que depende, pero aún necesita conocer la ruta absoluta. En este momento se requiere el cargador dinámico del sistema (dynamic linker/loader).
2) Para los programas ejecutables en formato ELF, esto lo realiza ld-linux.so*; busca en el orden siguiente: la sección DT_RPATH del archivo ELF — la variable de entorno LD_LIBRARY_PATH — la lista de archivos /etc/ld.so.cache — los directorios /lib/ y /usr/lib; al encontrar el archivo de biblioteca, lo carga en memoria.
Cómo hacer que el sistema pueda encontrarla:
- Si se instala en /lib o /usr/lib, entonces ld puede encontrarla por defecto, sin necesidad de hacer nada más.
- Si se instala en otro directorio, hay que añadirla al archivo /etc/ld.so.cache; los pasos son los siguientes:
-- Editar el archivo /etc/ld.so.conf y añadir la ruta del directorio donde se encuentra el archivo de biblioteca
-- Ejecutar ldconfig; este comando reconstruirá el archivo /etc/ld.so.cache
Copiamos la biblioteca dinámica creada a /usr/lib y luego ejecutamos el programa de prueba.
3.3. Creación y uso de bibliotecas dinámicas en Windows
3.3.1. Creación de bibliotecas dinámicas (.dll)
En comparación con Linux, crear una biblioteca dinámica en el sistema Windows es un poco más complicado. Primero, se necesita una función DllMain que sirva como punto de entrada de inicialización (al crear un programa de consola Win32, marcar el tipo DLL generará automáticamente este archivo):
| Archivo de entrada dllmain.cpp |
// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
|
Normalmente, al declarar las funciones exportadas, se necesita la palabra clave _declspec(dllexport):
| Archivo de cabecera DynamicMath.h |
#pragma once
class DynamicMath
{
public:
__declspec(dllexport) DynamicMath(void);
__declspec(dllexport) ~DynamicMath(void);
static __declspec(dllexport) double add(double a, double b);//加法
static __declspec(dllexport) double sub(double a, double b);//减法
static __declspec(dllexport) double mul(double a, double b);//乘法
static __declspec(dllexport) double div(double a, double b);//除法
__declspec(dllexport) void print();
};
|
Para generar la biblioteca dinámica es necesario configurar las propiedades del proyecto: abrir el "Panel de propiedades" del proyecto -- "Propiedades de configuración" -- "General", y en "Tipo de configuración" seleccionar "Biblioteca dinámica".
Figura: Configuración de propiedades del proyecto de biblioteca dinámica
Al compilar (Build) el proyecto se generará la biblioteca dinámica.
3.3.2. Uso de bibliotecas dinámicas
Crear un programa de prueba de consola Win32:
| Programa de prueba TestDynamicLibrary.cpp |
#include "stdafx.h"
#include "DynamicMath.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
double a = 10;
double b = 2;
cout << "a + b = " << DynamicMath::add(a, b) << endl;
cout << "a - b = " << DynamicMath::sub(a, b) << endl;
cout << "a * b = " << DynamicMath::mul(a, b) << endl;
cout << "a / b = " << DynamicMath::div(a, b) << endl;
DynamicMath dyn;
dyn.print();
system("pause");
return 0;
}
|
Método 1:
- Proyecto "Panel de propiedades" -- "Propiedades comunes" -- "Marcos y referencias" -- "Agregar referencia"; se mostrará el cuadro de diálogo "Agregar referencia". La pestaña "Proyectos" lista los proyectos de la solución actual y todas las bibliotecas que se pueden referenciar. En la pestaña "Proyectos", seleccione DynamicLibrary. Haga clic en "Aceptar".
- Para agregar el directorio del archivo de cabecera DynamicMath.h, se debe modificar la ruta de los directorios de inclusión. Abra el "Panel de propiedades" del proyecto -- "Propiedades de configuración" -- "C/C++" -- "General", y en el valor de la propiedad "Directorios de inclusión adicionales", escriba la ruta del directorio donde se encuentra DynamicMath.h o navegue hasta ese directorio.
Compilar y ejecutar: OK.
Figura: Resultado de la prueba de la biblioteca dinámica (VS)
Método 2:
- "Panel de propiedades" -- "Propiedades de configuración" -- "Enlazador" -- "General"; en "Directorios de bibliotecas adicionales", introduzca el directorio donde se encuentra la biblioteca dinámica.
- "Panel de propiedades" -- "Propiedades de configuración" -- "Enlazador" -- "Entrada"; en "Dependencias adicionales", introduzca DynamicLibrary.lib generado al compilar la biblioteca dinámica.
Aquí puede surgir una duda: ¿por qué la biblioteca dinámica también tiene un archivo DynamicLibrary.lib? Es decir, tanto la biblioteca de enlace estático como la de enlace dinámico terminan teniendo un archivo lib; entonces, ¿cuál es la diferencia entre ambos? En realidad, son dos cosas completamente distintas.
El tamaño de StaticLibrary.lib es de 190KB, el de DynamicLibrary.lib es de 3KB; el archivo lib correspondiente a la biblioteca estática se llamabiblioteca estática, y el archivo lib correspondiente a la biblioteca dinámica se llama [biblioteca de importación]. En realidad, la biblioteca estática en sí ya contiene el código de ejecución real, la tabla de símbolos, etc., mientras quepara la biblioteca de importación, su código de ejecución real se encuentra en la biblioteca dinámica; esta solo contiene la tabla de símbolos de direcciones, etc., para garantizar que el programa encuentre cierta información básica de direcciones de las funciones correspondientes.。
4. Llamada explícita a bibliotecas dinámicas
El método de uso de bibliotecas dinámicas presentado anteriormente es similar al de las bibliotecas estáticas y pertenece a la llamada implícita; al compilar se especifican la biblioteca correspondiente y la ruta de búsqueda. En realidad, las bibliotecas dinámicas también se pueden llamar explícitamente.[EnCel lenguaje], ¡llamar explícitamente a una biblioteca dinámica es facilísimo!
4.1. Llamada explícita a bibliotecas dinámicas en Linux
#include <dlfcn.h>, que proporciona las siguientes interfaces:
- void * dlopen( const char *pathname, int mode ): la función abre el archivo de biblioteca de enlace dinámico especificado en el modo especificado y devuelve un manejador al proceso que la llama.
- void* dlsym(void* handle, const char* symbol): dlsym, basándose en el manejador (pHandle) y el símbolo (symbol) de la biblioteca de enlace dinámico, devuelve la dirección correspondiente al símbolo. Con esta función no solo se puede obtener la dirección de una función, sino también la dirección de una variable.
- int dlclose(void *handle): dlclose se utiliza para cerrar la biblioteca de enlace dinámico del manejador especificado; solo cuando el contador de uso de esta biblioteca de enlace dinámico llega a 0, el sistema la descarga realmente.
- const char *dlerror(void): cuando las funciones de operación de la biblioteca de enlace dinámico fallan al ejecutarse, dlerror puede devolver el mensaje de error; si el valor de retorno es NULL, significa que la operación se ejecutó correctamente.
4.2. Llamada explícita a bibliotecas dinámicas en Windows
La aplicación debe realizar llamadas a funciones para cargar explícitamente la DLL en tiempo de ejecución. Para vincularse explícitamente a una DLL, la aplicación debe:
- Llamar aLoadLibrary(o una función similar) para cargar la DLL y obtener el manejador del módulo.
- Llamar aGetProcAddress, para obtener un puntero a función de cada función exportada que la aplicación deba llamar. Dado que la aplicación llama a las funciones de la DLL a través de punteros, el compilador no genera referencias externas, por lo que no es necesario vincular con la biblioteca de importación.
- Después de usar la DLL, llamar aFreeLibrary。
4.3. Puntos a tener en cuenta al llamar explícitamente a bibliotecas dinámicas de C++
Para C++, la situación es un poco más complicada. La dificultad de cargar explícitamente una biblioteca dinámica de C++se debe en parte ael name mangling de C++;y en parte porque no se proporciona unAPImecanismo adecuado para cargar clases,en C++, es posible que necesite usar una clase de la biblioteca, y esto requiere crear una instancia de dicha clase, lo cual no es fácil de lograr.
name manglingSe puede resolver mediante extern "C". C++ tiene una palabra clave específica para declarar funciones con binding de C: extern "C". Las funciones declaradas con extern "C" usarán el nombre de la función como nombre de símbolo, igual que las funciones de C. Por lo tanto, solo las funciones no miembro pueden declararse como extern "C" y no pueden sobrecargarse. A pesar de las muchas limitaciones, las funciones extern "C" son muy útiles porque pueden cargarse dinámicamente con dlopen como las funciones de C. Agregar el calificador extern "C" no significa que no se pueda usar código C++ dentro de la función; al contrario, sigue siendo una función C++ completa y puede usar cualquier característica de C++ y varios tipos de parámetros.
Además, sobre cómo obtener clases de una biblioteca dinámica de C++, adjunto algunos artículos relacionados, pero no recomiendo hacerlo:
- «LoadLibrary para invocar la Class en una DLL»:http://www.cppblog.com/codejie/archive/2009/09/24/97141.html
- 《C++ dlopen mini HOWTO》:http://blog.csdn.net/denny_233/article/details/7255673
Usar "explícitamente" la Class en una biblioteca dinámica de C++ es algo muy tedioso y peligroso; por lo tanto, si se puede usar "implícitamente", no use "explícitamente"; si se puede usar estática, no use dinámica.
5. Anexo: comandos relacionados con bibliotecas en Linux
5.1. Opciones de compilación de g++ (gcc)
- -shared: especifica generar una biblioteca de enlace dinámico.
- -static: especifica generar una biblioteca de enlace estático.
- -fPIC: indica compilar como código independiente de posición, utilizado para compilar bibliotecas compartidas. Los archivos objeto deben crearse como código independiente de posición; conceptualmente, cuando el programa ejecutable los carga, pueden colocarse en cualquier lugar de la memoria del programa ejecutable.
- -L.: indica el directorio donde se encuentra la biblioteca a enlazar.
- -l: especifica la biblioteca dinámica necesaria al enlazar. El compilador tiene una regla de nomenclatura implícita al buscar bibliotecas de enlace dinámico: antepone "lib" al nombre dado y añade ".a/.so" para determinar el nombre de la biblioteca.
- -Wall: genera toda la información de advertencia.
- -ggdb: esta opción generará, en la medida de lo posible, información de depuración utilizable por gdb.
- -g: el compilador genera información de depuración al compilar.
- -c: solo activa el preprocesado, la compilación y el ensamblado, es decir, convierte el programa en un archivo objeto (archivo .o).
- -Wl,options: pasa los argumentos (options) al enlazador ld. Si hay comas en options, divide options en múltiples opciones y luego las pasa al programa enlazador.
5.2. Comando nm
A veces puede ser necesario ver qué funciones contiene realmente una biblioteca,nmel comandopuede imprimir todos los símbolos involucrados en la biblioteca. La biblioteca puede ser estática o dinámica. Los símbolos listados por nm son muchos; hay tres tipos comunes:
- Uno es invocado en la biblioteca pero no está definido en ella (indica que se necesita el soporte de otras bibliotecas), representado con U;
- Uno es una función definida en la biblioteca, representada con T; este es el más común;
- Uno es el llamado símbolo "débil"; aunque está definido en la biblioteca, puede ser sobrescrito por símbolos del mismo nombre en otras bibliotecas, representado con W.
$nm libhello.h
5.3. Comando ldd
lddEl comando puede ver las bibliotecas compartidas de las que depende un programa ejecutable,por ejemplo, la biblioteca dinámica de operaciones aritméticas que escribimos depende de las siguientes bibliotecas:
6. Resumen
La diferencia entre ambos radica enque el momento en que el código se carga es diferente.。
- La biblioteca estática se enlaza al código objeto durante la compilación del programa; en tiempo de ejecución, el programa ya no necesitará esa biblioteca estática,por lo que su tamaño es mayor.。
- La biblioteca dinámica no se enlaza al código objeto durante la compilación del programa, sino que se carga cuando el programa se ejecuta; por lo tanto, la biblioteca dinámica debe existir durante la ejecución del programa,por lo que el tamaño del código es menor.。
La ventaja de las bibliotecas dinámicas es que si diferentes aplicaciones llaman a la misma biblioteca, solo se necesita una instancia de esa biblioteca compartida en memoria. Pero junto con las ventajas, también hay problemas, como el clásico problema de DLL Hell. Sobre cómo evitar los problemas de gestión de bibliotecas dinámicas, se puede buscar información relevante por su cuenta.
7. Tutoriales relacionados
Tutorial de C++:http://www.w3cschool.cc/cplusplus/cpp-tutorial.html
Autor: Wu Qin
Fuente: http://www.cnblogs.com/skynet/
![clip_image002[4] clip_image002[4]](../wp-content/uploads/2015/05/16201601-66b55a2f0ec74c5b8a773a0e1904e812.png.webp)
![clip_image004[4] clip_image004[4]](../wp-content/uploads/2015/05/16201602-e0b2900a915d4dce8b4af5153c8b2d72.png.webp)
![clip_image006[4] clip_image006[4]](../wp-content/uploads/2015/05/16201604-713c3a4a83aa4c17868a16f13b49027b.jpg.webp)
![clip_image008[4] clip_image008[4]](../wp-content/uploads/2015/05/16201604-ae57e89353c74265a0f1d26e89ffdbd5.jpg.webp)
![clip_image010[4] clip_image010[4]](/wp-content/uploads/2015/05/16201605-6a3acac10b40402ea99343ad092f0061.jpg.webp)
![clip_image012[4] clip_image012[4]](../wp-content/uploads/2015/05/16201607-fed082fd8a134770b24c2b4569ad4405.jpg.webp)
![clip_image014[4] clip_image014[4]](../wp-content/uploads/2015/05/16201609-9be107869b604f53bc08653fe28bfbad.jpg.webp)
![clip_image015[4] clip_image015[4]](../wp-content/uploads/2015/05/16201610-8630c9a19cae4143bffacd255367ffbb.png.webp)
![clip_image017[4] clip_image017[4]](/wp-content/uploads/2015/05/16201610-2bde8b094f5a4603848c574f1f228144.jpg.webp)
![clip_image019[4] clip_image019[4]](../wp-content/uploads/2015/05/16201612-3af709f047ca4964898f3ce29680093c.jpg.webp)
![clip_image021[4] clip_image021[4]](../wp-content/uploads/2015/05/16201613-1320ec57feb24583a6b1294421c323b8.png.webp)
![clip_image023[4] clip_image023[4]](../wp-content/uploads/2015/05/16201613-110ca9e0fd684281b3ee6d9bd9bebd78.png.webp)
![clip_image025[4] clip_image025[4]](../wp-content/uploads/2015/05/16201614-02f4340b15664f8a83282fb9a27ca3e5.jpg.webp)
![clip_image027[4] clip_image027[4]](../wp-content/uploads/2015/05/16201616-45dcaece0519453c96dfd1972295cd92.jpg.webp)
![clip_image029[4] clip_image029[4]](../wp-content/uploads/2015/05/16201617-93f234207a9947a6a1caadd8acd9ead7.jpg.webp)
![clip_image031[4] clip_image031[4]](../wp-content/uploads/2015/05/16201618-a32a866f00c84a74893fa2181fa27b11.jpg.webp)
![clip_image033[4] clip_image033[4]](/wp-content/uploads/2015/05/16201619-f190d6dd94ee48e0883bb5d5bbe4e66a.jpg.webp)
![clip_image035[4] clip_image035[4]](../wp-content/uploads/2015/05/16201623-914ff83612a4470fa59c2bc729053c6b.jpg.webp)
![clip_image037[4] clip_image037[4]](../wp-content/uploads/2015/05/16201624-9cfecaf931ba4f4d96d6cf7cac3ac40e.jpg.webp)
![clip_image038[4] clip_image038[4]](../wp-content/uploads/2015/05/16201626-29defaed72cf4a91b7c83f6bd0fecf53.png.webp)
![clip_image040[4] clip_image040[4]](/wp-content/uploads/2015/05/16201626-98727f19e0d14d43942771bac7e24238.jpg.webp)
![clip_image042[4] clip_image042[4]](../wp-content/uploads/2015/05/16201628-425bd512f3bf4b51b121bdb59604bc5e.jpg.webp)
![clip_image044[4] clip_image044[4]](../wp-content/uploads/2015/05/16201631-f72543fd66ba4593996f864a7fb6f92a.jpg.webp)
![clip_image046[4] clip_image046[4]](../wp-content/uploads/2015/05/16201633-aebe0e8017354a9b93644043b9d013c6.jpg.webp)