2010-08-30 25 views
5

Soy nuevo en vC++. Acabo de construir un software y generó un .dll y un .lib. Necesito usar funciones de esto en mi código. ¿Necesito vincular tanto .lib como .dll para construir mi código? ¿Qué propiedades del proyecto debo modificar para hacer esto?.h, .dll y .lib confusion

+0

ver también http://stackoverflow.com/questions/1778111/whats-the-differences-between-dll-lib-h-files – dyp

Respuesta

10

En realidad, solo necesita el archivo .dll. Contiene todos los códigos y datos necesarios para ejecutar sus funciones. También contiene una tabla que vincula los nombres simbólicos de las funciones (por ejemplo, la función PrintMe), sus ordinales (el número de esa función en la DLL) y sus direcciones en la DLL.
Si desea utilizar solo el archivo DLL, debe "resolver" manualmente los símbolos:
Digamos que desea utilizar la función PrintMe del archivo DLL. Lo que tiene que hacer es resolver su nombre (PrintMe) o su ordinal (PrintMe es la primera función de la DLL) en su dirección. Para esto, puede usar LoadLibrary, GetModuleHandle y GetProcAdress de la API Win32 (también conocida como Windows SDK). Además, este método le permite cargar la DLL en tiempo de ejecución (ver a continuación).

La forma más fácil es utilizar las características MSVC (++) __declspec (dllexport) y __declspec (dllimport), p. Ej.


// your DLL 
__declspec(dllexport) void PrintMe() 
{ 
    printf("Hello World!"); 
} 

// you project to use the DLL 
__declspec(dllimport) void PrintMe(); 

El primero (dllexport) le dice al compilador que exporte la función. El segundo (dllimport) es el más interesante: crea todo el código necesario para poder usar la función desde el DLL.
Para esto, necesita el archivo .lib en su proyecto (que quiere usar el DLL). El archivo .lib contiene información para que el vinculador resuelva el nombre del símbolo (PrintMe) en su dirección en la DLL. Como el archivo .lib está enlazado estáticamente, el enlazador puede usarlo, el DLL, por el contrario, está vinculado durante el tiempo de ejecución/carga, por lo que el vinculador no puede usarlo. (Sí, la información en el archivo .lib es redundante). Nota: No puede cambiar la DLL completa al usar este método sin reconstruir su proyecto con el nuevo archivo .lib. Algunos cambios de estructura afectan las direcciones de las funciones en el archivo DLL, consulte this SO answer.
Una última diferencia entre usar la API Win32 (LoadLibrary ...) y el método MSVC a través de __declspec es la carga de la DLL. Cuando usa LoadLibrary, la DLL se carga en tiempo de ejecución, por supuesto (para que pueda detectar excepciones cuando no se puede encontrar, etc.). El otro método carga la DLL en el momento de la carga, por lo que su programa terminará (no se ejecutará) cuando Windows no pueda encontrar la DLL.

Cuando crea un proyecto en VS, puede activar la casilla de verificación "exportar símbolos" al final de un asistente (proyecto Win32). Eso le da algunos ejemplos de símbolos exportados. Además, se introduce una macro más un defition preprocesador además de algunas directivas que son muy útiles:


// DLL header 

#ifdef _YOUR_DLL_EXPORTS 
#define YOUR_DLL_API __declspec(dllexport) 
#else 
#define YOUR_DLL_API __declspec(dllimport) 
#endif 

YOUR_DLL_API PrintMe(); 

Ahora puede utilizar este archivo de cabecera para construir el edificio DLL como su proyecto DLL tiene que _YOUR_DLL_EXPORTS definición (véase la página de propiedades del proyecto, C++, preprocesador). El proyecto que usa el DLL también puede usar este encabezado, pero no debe tener dicho nombre definido. Cuando incluye el archivo de encabezado en el proyecto en el que desea usar el archivo DLL, la macro se resuelve en __declspec (dllimport). Esto le indica al vinculador que busque esta función (que se encuentra en el archivo .lib) y crea todo el código necesario para cargar el archivo DLL en tiempo de ejecución y resolver el nombre del símbolo.

+0

+1. Ojalá pudiera votar esto más. –

+1

Debe tenerse en cuenta que también hay algo que se llama comprobación de "Importar biblioteca" http://stackoverflow.com/questions/3573475/how-does-the-import-library-work-details –

+0

@WakanTanka Sí, ese es el tipo de .lib que estaba hablando en mi respuesta. Gracias por el enlace. – dyp