您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

6.7 KiB

库相关知识点

静态库

静态库的基本概念

静态库(Static Library)是一种预先编译好的程序代码集合,以独立文件形式存在,供其他程序在编译时链接使用。它将多个目标文件(.o 或 .obj)打包为单一文件,简化了程序开发和部署流程。

核心特点

  1. 编译时链接
    链接器在编译阶段将静态库中的代码完整复制到可执行文件中,运行时无需依赖外部库文件。
  2. 独立性
    生成的可执行文件不依赖外部库,便于在不同环境中部署,但会导致文件体积增大。
  3. 格式差异
    • Windows:通常以 .lib 为扩展名
    • Unix/Linux/macOS:使用 .a(archive)扩展名

静态库的生成

使用vs2022选择C++静态库创建

image-20250709185110253

写完代码,点击生成即可生产.lab文件

image-20250709190120328

image-20250709190224585

静态库的调用

在工程配置中调用

  1. 配置静态库的头文件选择属性>C/C++>附加包含目录将头文件目录配置上去

image-20250709191548096

  1. 配置静态库的所在位置,选择属性>链接器>常规>附加库目录配置其所在路径

image-20250709191834414

  1. 配置静态库的所在位置,选择属性>链接器>输入>附加依赖项配置其名字

image-20250709192153729

  1. 可以直接使用#include <StaticLib.h>

image-20250709192522012

在代码中语句加载lib调用

先把需要引用的头文件还有.lib文件放在一起

//第一行是引用头文件
//第二行是引用静态库
#include "C:\\Users\\徐加冠\\source\\repos\\LabTest\\x64\\Debug\\StaticLib.h"
#pragma comment(lib,"C:\\Users\\徐加冠\\source\\repos\\LabTest\\x64\\Debug\\StaticLib.lib")

image-20250709191259138

动态库

动态库的基本概念

动态库(Dynamic Library)是一种在程序运行时才被链接和加载的共享库文件,包含可被多个程序同时使用的代码和数据。与静态库(Static Library)在编译时被完整嵌入到可执行文件中不同,动态库在运行时才被动态加载到内存,实现代码复用并减少内存占用。

核心特点

  1. 共享加载:多个程序可共享同一份动态库实例,减少内存开销。
  2. 运行时链接:程序启动时才加载动态库,而非编译时,提高开发灵活性。
  3. 独立更新:动态库可独立于程序更新,无需重新编译整个程序。
  4. 跨平台差异:
    • Windows:以 .dll(Dynamic Link Library)为扩展名。
    • Linux/macOS:以 .so(Shared Object)或 .dylib(Dynamic Library)为扩展名。

动态库的生成

通过导出语句生成

  1. 使用vs2022选择动态链接库创建空项目

image-20250710102828844

  1. 分别添加头文件和源文件

头文件的导出语句

#pragma once
 
#ifndef BHDLL_d
#define BHDLL_d
 
//宏定义导出
#ifdef BHDLL__//如果没有定义DLLH 就定义 DLLH __declspec(dllexport)
#define BHDLL __declspec(dllexport)//导出
#else
#define BHDLL __declspec(dllimport)//导入
#endif // DLLH__//如果没有定义DLLH 就定义 DLLH 
 
//编写代码区域
 
//导出函数
 
BHDLL int add(int a, int b);
BHDLL int sub(int a, int b);
 
//导出类
 
class BHDLL dllH
{
public:
  int mul(int a, int b);
  int div(int a, int b);
};
 
//以C语言方式导出函数:
extern "C"
{
  BHDLL int Cadd(int a, int b);
  BHDLL int Csub(int a, int b);
}
 
 
 
#endif

源文件代码

#include "BH_dll.h"
#include <iostream>
 
using namespace std;
 
int add(int a, int b)
{
  return a + b;
}
int sub(int a, int b)
{
  return a - b;
}
 
int dllH::mul(int a, int b)
{
  return a * b;
}
int dllH::div(int a, int b)
{
  return a / b;
}
 
int Cadd(int a, int b)
{
  return a + b;
}
int Csub(int a, int b)
{
  return a - b;
}
  1. 修改项目属性改为dll动态库

image-20250710103417243

点击重新生成,即可生成动态链接库

image-20250710103520461

通过模块文件生成

  1. 使用vs2022创建一个空项目

image-20250710104736756

  1. 创建一个源文件
#include "iostream"
void fun1()
{
	std::cout << "fun1" << std::endl;
}
void fun2()
{
	std::cout << "fun2" << std::endl;
}

  1. 创建一个edf配置文件
LIBRARY "test"

EXPORTS
fun1
fun2
  1. 修改项目的生成为.dll和输出的名字和上面LIBRARY "test"定义的名字要一致

image-20250710105048084

  1. 定义模块文件的位置点击链接器>输入>模块定义文件

image-20250710195629035

  1. 点击重新生成就可以生成

image-20250710105215199

动态库的调用

在工程配置中调用

  1. 点击项目属性配置其C\C++>附加包含目录,改成需要调用dll所在目录

image-20250710123819771

  1. 点击链接器>常规>附加库目录

image-20250710124000084

  1. 点击链接器>输入>附加依赖项输入调用名字

image-20250710124140907

  1. 运行代码时需要把dll放在exe同文件夹下,不然会报错

image-20250710124556617

  1. 放在相同目录下运行成功

image-20250710124711322

在代码中语句加载lib调用

#include "D:\\桌面\\x64\\Debug\\DllMy.h"
#pragma comment(lib,"D:\\桌面\\x64\\Debug\\DllMy.lib")

image-20250710125301402

在代码中语句加载dll调用

HINSTANCE Dll = LoadLibrary(L"test.dll");
if (Dll == NULL) {
    std::cerr << "无法加载DLL! 错误码: " << GetLastError() << std::endl;
    return 1;
}
typedef void (*Func)(); // 定义函数指针类型
Func add = (Func)GetProcAddress(Dll, "fun1");
add();
FreeLibrary(Dll);
return 0;

image-20250710130734676

ps:如果使用导出语句生成的dll,dll内部的函数名称和你定义的不一样,如果使用edf文件导出可以自定义函数名称