Uso de biblioteca estática (lib) y biblioteca dinámica (dll)


Prefacio

  Las bibliotecas estáticas y las bibliotecas dinámicas se utilizan con mucha frecuencia en el desarrollo de software de Windows. Muchas funciones de una buena arquitectura de software se encuentran en forma de bibliotecas. Si es necesario actualizar la función, el archivo de la biblioteca se puede reemplazar directamente sin actualizar todo el programa. Esto es más conveniente de mantener.

  Los archivos de biblioteca comunes tienen dos formas, .lib y .dll , que son bibliotecas estáticas y bibliotecas dinámicas.

  Cuando la biblioteca estática se forma en un archivo exe, todos se empaquetan en formato.

  La biblioteca dinámica solo se importa al archivo ejecutable cuando se está ejecutando y se puede cargar y descargar dinámicamente.


Uno, la comprensión de la sobrecarga de funciones.

  C ++ admite la sobrecarga de funciones, pero C no admite la sobrecarga de funciones.

  Una vez compiladas las funciones con el mismo nombre en C, los nombres de las funciones son los mismos. Tomando VS como ejemplo, todas comienzan con un guión bajo "_", por lo que si llama, no sabe a qué función llamar, por lo que C no admite la sobrecarga.
  Cdecl es este tipo de método de llamada, que busca directamente el nombre de la función original, sin agregar ninguna decoración al nombre de la función.

Inserte la descripción de la imagen aquí

  Después de compilar la función del mismo nombre en C ++, el compilador agregará significados como el tipo de parámetro y el número de parámetro al nombre de la función para distinguir, es decir, cada nombre de función es diferente y se puede distinguir, por lo que C ++ admite la sobrecarga. (La regla de nomenclatura en C ++: Name-Mangling)
  (Cada función con el mismo nombre con diferentes parámetros que se muestra en la imagen de abajo tiene un nombre diferente para la función compilada más adelante)
  Este método de llamada de stdcall agregará parámetros y otras decoraciones al original nombre de la función. Se utiliza para distinguir la misma función, pero el cuerpo de la función y los parámetros son diferentes cuando la función está sobrecargada.

Inserte la descripción de la imagen aquí


2. Comprensión de la "C" externa

  Como se mencionó anteriormente, después de que C ++ compila una función, su nombre se modificará nuevamente, agregando información de parámetros, entonces la función C ++ y la función C no se pueden llamar entre sí, porque los nombres de sus funciones respectivas son diferentes después de la compilación, y se encontrarán cuando Se informa de un error si el nombre de la función no está disponible . Pero en la práctica, es posible, lo que indica que se ha realizado cierto procesamiento.

  Este es el papel del externo "C".

  Su función es generar el nombre de la función de la misma forma que el nombre de la función se genera en C.

Inserte la descripción de la imagen aquí

  En este caso, incluso si los compiladores respectivos no utilizan el método de generación de nombres de funciones, todos se generan de acuerdo con el estándar C , por lo que pueden llamarse entre sí. Por lo tanto, si la biblioteca dinámica se va a llamar externamente, esta modificación generalmente se requiere .


Tres, la llamada de la biblioteca estática

1. La generación de biblioteca estática

(1) Generar biblioteca estática (lib)

  Primero haga clic en la biblioteca estática (Visual C ++), luego, después de seleccionar el directorio, haga clic en Aceptar.

Inserte la descripción de la imagen aquí
  Puede eliminar otros archivos, dejando solo pch.hy pch.cpp,

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí
Programa de biblioteca estática .h

#ifndef PCH_H
#define PCH_H

#include <iostream>


void Print();
int Add(int a, int b);

#endif //PCH_H

Inserte la descripción de la imagen aquí
Programa estático library.cpp

#include "pch.h"

using namespace std;
void Print()
{
    
    
	cout << "I am a smart boy!" << endl;
	cout << "666!" << endl;
	cout << "you are a pretty girl!" << endl;
}

int Add(int a, int b)
{
    
    
	return ((a)+(b));
}

  Finalmente, haga clic en Generar y verá que se genera el archivo lib.

Inserte la descripción de la imagen aquí


2. La llamada de la biblioteca estática

  Hay tres formas, importación de programa, importación de archivo de recursos e importación de compilador.

  Independientemente del método de importación, debe importar el archivo de encabezado de la biblioteca . En este artículo, debe agregar el archivo pch.h, y la ruta de su .h también debe agregarse en el proyecto- "Propiedades - "Directorio C / C ++-" Directorio adicional Agregue el directorio del archivo .h.

Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí

  1. Importar a través del programa (la ruta debe usar \ \ )

Inserte la descripción de la imagen aquí

#include <iostream>
#include "pch.h"

#pragma comment(lib, "D:\\guoqing.zhang\\StaticLibrary\\StaticLib\\Debug\\StaticLib.lib")

int main()
{
    
    
	Print();
	std::cout << Add(3, 6) << std::endl;
}
  1. Importación de archivos de recursos
    Inserte la descripción de la imagen aquí
  2. Importación del compilador

  Proyecto- "Propiedades-" Vinculador- "Directorio de biblioteca adicional en general, para agregar la ruta de la biblioteca estática.

Inserte la descripción de la imagen aquí

  Proyecto- "Propiedades-" Vinculador - "ingrese dependencias adicionales, debe agregar el nombre de la biblioteca estática.

Inserte la descripción de la imagen aquí

  No importa qué tipo de adición se complete, agregue "pch.h" al archivo de función principal, haga clic en Depurar y verá el resultado de la ejecución.

Inserte la descripción de la imagen aquí


Cuarto, la llamada de la biblioteca dinámica.

1. Generación de bibliotecas dinámicas

  Haga clic en Proyecto- "Nuevo proyecto-" DLL de biblioteca de vínculos dinámicos, y el proyecto se puede generar después de seleccionar la ruta. Puede dejar solo un archivo .hy un archivo .cpp, y los demás se pueden eliminar.

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí
Programa dinámico library.h

#pragma once

#ifndef DLL_H
#define DLL_H

#define  LIB_API extern "C" __declspec(dllexport)
#include <iostream>

LIB_API void Demo();
LIB_API int Sub(int a, int b);
#endif //PCH_H

Inserte la descripción de la imagen aquí
Programa de biblioteca dinámica .cpp

#include "Dll.h"
#include "pch.h"

LIB_API void Demo()
{
    
    
	Print();
	std::cout << Add(3, 5) << std::endl;
}

LIB_API int Sub(int a, int b)
{
    
    
	return ((a)-(b));
}

  Así es, después de leerlo, encontrará que la biblioteca dinámica puede llamar a la biblioteca estática. La biblioteca Dll en este artículo llama al StaticLib.lib generado antes, agregando el archivo de encabezado de la biblioteca estática.

  Esta es también la diferencia entre una biblioteca estática y una biblioteca dinámica . Una biblioteca dinámica puede incluir otras bibliotecas estáticas o bibliotecas dinámicas, mientras que una biblioteca estática no puede incluir otras bibliotecas estáticas o bibliotecas dinámicas.

  Después de programar, haga clic en Generar, puede ver que hay una biblioteca .dll generada, ingrese a su carpeta, encontrará que hay un archivo .lib correspondiente generado, este no es un programa de biblioteca, solo el nombre de la función y la ubicación del dll , que es conveniente para encontrar la entidad Función .dll.

Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí
  Si encuentra un error como el error en la figura siguiente, es un problema con el encabezado precompilado. Puede completar la compilación normalmente eligiendo no usar el encabezado precompilado. (El archivo precompilado se elimina).

Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí

2. La llamada de la biblioteca dinámica

Llamada implícita : coloque Dll.dll, Dll.lib y Dll.h en el directorio del proyecto.

Inserte la descripción de la imagen aquí
  Vinculador: "Ingrese para agregar dependencias adicionales, seleccione Dll.lib,

Inserte la descripción de la imagen aquí
  Dll.lib se puede agregar al archivo de recursos o la dependencia de datos adjuntos y luego agregar el archivo de encabezado "Dll.h" a la función principal, llamar a la función en la biblioteca,
Inserte la descripción de la imagen aquí
  hacer clic en Depurar y se puede ejecutar normalmente.
Inserte la descripción de la imagen aquí
Llamada explícita : sin agregar archivos .hy archivos .lib, importe directamente la biblioteca dll y llame a las funciones en la biblioteca a través del puntero de función. El proceso específico es el siguiente:

1. Importe la biblioteca dll LoadLibrary (nombre de la biblioteca)
2. El puntero del constructor debe ser coherente con la función en el archivo de la biblioteca, incluidos los parámetros y tipos de función.
3. Obtenga la dirección de la función a través del puntero de función, GetProcAddress (identificador, nombre de la función / número de función); (número de función: el orden en el que se declara la función en .h)
4. Utilice el puntero de función para llamar a la función

#include <iostream>
#include <Windows.h>
int main()
{
    
    
    std::cout << "Hello World!\n";
	//1、导入dll库
	HMODULE h = LoadLibrary(L"Dll.dll");
	//2、构造函数指针
	typedef int(*PSUM) (int, int);//
	//3、利用函数指针调用函数
	PSUM psum =(PSUM)GetProcAddress(h,"Sub");//利用函数名
	//PSUM psum = (PSUM)GetProcAddress(h, (char*)2);//利用函数序号
	std::cout << psum(11, 22) << std::endl << std::endl;

	typedef void(*PDemp) ();//
	//3、利用函数指针调用函数
	/*PSUM psum =(PSUM)GetProcAddress(h,"sum");*///利用函数名
	PDemp pdemo = (PDemp)GetProcAddress(h, (char*)1);//利用函数序号
	pdemo();

	//4、释放DLL
	FreeLibrary(h);
	return 0;
}

Llamado con éxito.
Inserte la descripción de la imagen aquí

  Si se descubre que no se puede encontrar el nombre de la función y no se puede completar el enlace dinámico, es posible que el nombre de la función en la biblioteca formada no coincida con el nombre de la función enlazada . (Hay uno que se ha modificado agregando información y el otro no está modificado) (error en la imagen de abajo)

Obtenga la función en el dll a   través de la función GetProcAddress . La función exportada en el dll debe estar decorada con extern "C", de lo contrario no se puede encontrar la dirección de la función. (La razón es que el Name-Mangling de C ++ modifica la regla del nombre de la función ).
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí
Descarga de código de ejemplo

Supongo que te gusta

Origin blog.csdn.net/qq_34430371/article/details/111354711
Recomendado
Clasificación