「C/C++」C/C++静态链接库与动态链接库

article/2025/9/29 8:58:26

在这里插入图片描述

博客主页:何曾参静谧的博客
文章专栏:「C/C++」C/C++学习

目录

  • 相关术语
  • 案例环境:Win10+VS2019
  • 一、链接库介绍
  • 二、静态链接库(Static Library)
    • 2.1、静态库优缺点
    • 2.2、静态库的创建
      • 2.2.1、创建静态库项目
      • 2.2.2、添加.h头文件和.cpp文件
      • 2.2.3、编译生成.lib文件
    • 2.3、静态库的使用
  • 三、动态链接库(Dynamic Linking Library)
    • 3.1、动态库优缺点
    • 3.2、动态库的创建
      • 3.2.1、创建动态库项目
      • 3.2.2、添加dllsum.h头文件和dllsum.cpp文件
      • 3.2.3、编译生成dllsum.lib与dllsum.dll文件
    • 3.3、动态库*.dll使用
      • 3.3.1方法一:直接使用
      • 3.3.2方法二:使用LoadLibrary()


相关术语

静态链接库(Static Linking Library):是在编译时将库代码与应用程序静态链接在一起的库。它们被编译为二进制文件,并在运行时作为应用程序的一部分被载入内存。这种库被称为“静态”是因为它们在编译时被链接,这意味着它们的代码与应用程序的其余部分被编译为单个二进制文件。文件后缀:.lib.a
动态链接库(Dynamic Linking Library):是在应用程序运行时才被加载到内存中的库。它们不会被编译为二进制文件,而是被存储为单独的文件。这些库共享代码,并被多个应用程序使用,以提高效率和避免代码冗余。文件后缀:.dll.so

案例环境:Win10+VS2019

代码的分发方式:

  1. 源码方式头文件+源文件
  2. 动态库方式头文件+lib文件+dll文件
  3. 静态库方式头文件+lib文件

一、链接库介绍

链接库(library)是一种常见的软件开发概念,指的是包含可重用代码的二进制文件(通常是动态链接库)。在运行时,程序可以将某个库链接到自己的代码中,从而使用该库中的函数和其他代码。链接库的使用可以提高代码的复用性、减少程序体积、加快编译速度等。

平台集静态库动态库
Windows.lib文件.dll文件
Linux.a文件.so文件
Mac OS.a文件.dylib文件

C语言和C++的常用的CRT,后面红色的d代表多线程,p代表C++

C语言C++
静态库libc.lib 或 libcd.lib
libcmt.lib 或 libcmtd.lib
LIBCP.LIB 或 LIBCPD.LIB
LIBCPMT.LIB 或 LIBCPMTD.LIB
动态库msvcrt.dll 或 msvcrtd.dllMSVCPRT.DLL 或 MSVCPRTD.DLL

二、静态链接库(Static Library)

静态链接库(Static Linking Library):是在编译时将库代码与应用程序静态链接在一起的库。它们被编译为二进制文件,并在运行时作为应用程序的一部分被载入内存。这种库被称为“静态”是因为它们在编译时被链接,这意味着它们的代码与应用程序的其余部分被编译为单个二进制文件。文件后缀:.lib.a

2.1、静态库优缺点

静态链接库的优点:

  • 一劳永逸:在程序编译时,所有需要的库的代码都被打包成一个可执行文件。这样一来,在将程序运行到其他机器上时,您不必再携带各种动态库而是只需一份可执行文件就好了。
  • 执行速度更快:因为所有代码都在一个文件中,所以不需要运行时加载,执行速度很快。
  • 不会出现库版本冲突问题

静态链接库的缺点:

  • 占用空间较大,相同功能的多个程序都要各自有一份库文件
  • 更新麻烦,每次修改库文件都需要重新编译与分发

2.2、静态库的创建

2.2.1、创建静态库项目

2.2.2、添加.h头文件和.cpp文件

以一个简单求和函数为案例,创建两个文件libsum.h,libsum.cpp

libsum.h文件

#pragma once
int sum(int a, int b);

libsum.cpp文件

#include "libsum.h"
int sum(int a, int b){return a + b;
}

2.2.3、编译生成.lib文件

2.3、静态库的使用

  • 包含头文件的libsum.h头文件#include"libsum.h"
  • 包含libsum.lib文件两种方法:
    – 方法一:文件中添加 #pragma comment(lib,"libsum.lib")
    – 方法二:右键项目->属性->配置属性->链接器->输入->附加依赖项->libsum.lib

main.cpp

#include"libsum.h"
#include <iostream>
#pragma comment(lib,"libsum.lib")int main(){cout << sum(11,22) << endls;return 0;
}

三、动态链接库(Dynamic Linking Library)

动态链接库(Dynamic Linking Library):是在应用程序运行时才被加载到内存中的库。它们不会被编译为二进制文件,而是被存储为单独的文件。这些库共享代码,并被多个应用程序使用,以提高效率和避免代码冗余。文件后缀:.lib.so

3.1、动态库优缺点

动态链接库的优点:

  • 节约内存和代码重用:当应用程序使用动态链接时,多个应用程序可以共享磁盘上单个DLL副本。
  • 便于更新和维护:只需替换动态链接库,程序就能获取新的功能。
  • 可扩展性:DLL文件与EXE文件独立,只要接口不变,升级程序只需要更新DLL文件不需要重新编译应用程序。
  • 复用性:DLL的编译与具体的编译语言及编译器无关,不同语言编写的程序只要按照函数调用约定就可以调用同一个DLL函数。

动态链接库的缺点:

  • DLL HELL(DLL地狱):在增加成员变量、修改导出类的基类等操作可能导致意想不到的后果。
  • 需要载入时才能使用,/runtime,例如QTGUI库
  • 多进程间的共享使用需要考虑锁的问题,
  • 存在库版本冲突问题

3.2、动态库的创建

3.2.1、创建动态库项目

3.2.2、添加dllsum.h头文件和dllsum.cpp文件

以一个简单求和函数为案例,创建两个文件dllsum.h,dllsum.cpp
需要使用到_declspec(dllexport)进行函数导出,extern"C"为强制使用C语言语法(无法函数重载)。

dllsum.h文件

#pragma once
extern"C" _declspec(dllexport) int sum(int a, int b);

dllsum.cpp文件

#include "dllsum.h"
int sum(int a, int b){return a + b;
}

3.2.3、编译生成dllsum.lib与dllsum.dll文件

PS:此处的.lib文件不是静态库文件而是dll的符号文件。

3.3、动态库*.dll使用

3.3.1方法一:直接使用

  • 包含头文件的头文件#include "dllsum.h"
  • 包含dllsum.lib文件两种方法:
    – 方法一:文件中添加 #pragma comment(lib,"dllsum.lib")
    – 方法二:右键项目->属性->配置属性->链接器->输入->附加依赖项->dllsum.lib
  • 🎈使用时文件中需要包含dllsum.dll文件

main.cpp

#include "dllsum.h"
#include <iostream>
#using namespace std;
#pragma comment(lib,"dllsum.lib")
extern "C"  _declspec(dllimport)  int sum(int a, int b);
int main(){cout << sum(11,22) << endl;return 0;
}

3.3.2方法二:使用LoadLibrary()

  • 加载动态库:LoadLibrary()
HMODULE WINAPI LoadLibrary(
_In_LPCWSTR lpLibFileName, //动态链接库的名称
);//返回值:调用成功,返回库模块的句柄。调用失败返回0。
  • 获取函数地址:GetProcAddress()
FARPROC WINAPI GetProcAddress(
HMODULE hModule, //模块的句柄
LPCSTR lpProcName //函数名 或 WORD叙数值
);//返回值:调用成功,输出函数地址。调用失败返回NULL。
  • 释放动态库:FreeLibrary()
BOOL WINAPI FreeLibrary(
_In_HMODULE hLibModule //模块的句柄
);
  • 获取错误信息:GetLastError()

main.cpp

#include <iostream>
#include <windows.h>
#using namespace std;int main(){//1.加载dllHMODULE h = LoadLibrary("dllsum.dll");//2.获取函数地址typedef int(*PDLLSUM)(int,int);//3.利用函数指针调用函数if(1)PDLLSUM pdllsum = (PDLLSUM)GetProcAddress(h,"sum");//通过函数名调用elsePDLLSUM pdllsum = (PDLLSUM)GetProcAddress(h,char*)1);//通过序号调用cout << pdllsum(11,22) << endl;//4.释放dllFreeLibrary(h);return 0;
}

在这里插入图片描述


http://chatgpt.dhexx.cn/article/bY64rXYn.shtml

相关文章

C++封装静态链接库及使用

一、为什么要把程序封装成库 有时我们需要把自己的程序交给第三方调用&#xff0c;但是又不想被别人看到自己的具体实现代码&#xff0c;就封装成库给别人使用。库有动态链接库和静态链接库&#xff0c;区别是动态链接库可以在程序运行时动态链接&#xff0c;而静态链接库相当于…

C++ 创建静态链接库和动态链接库

上篇文章演示了如何使用C 编译的静态链接库和动态链接库&#xff0c;本篇文章主要介绍如何创建静态链接库和动态链接库&#xff0c;本文使用的工具是visual studio 2019 企业版&#xff0c;需要安装对应的Csdk&#xff0c;可以参考网上其他文章&#xff0c;本问不在赘述。 一、…

动态链接库和静态链接库

转载自&#xff1a;https://www.cnblogs.com/king-lps/p/7757919.html &#xff08;有删减&#xff09; 1. 库的介绍 库是写好的现有的&#xff0c;成熟的&#xff0c;可以复用的代码。现实中每个程序都要依赖很多基础的底层库&#xff0c;不可能每个人的代码都从零开始&…

静态链接库与动态链接库----C/C++

平时我们写程序都必须include很多头文件&#xff0c;因为可以避免重复造轮子&#xff0c;软件大厦可不是单靠一个人就能完成的。但是你是否知道引用的那些头文件中的函数是怎么被执行的呢&#xff1f;这就要牵扯到链接库了&#xff01;&#xff01;&#xff01; 库有两种&#…

【四、静态库与动态库(共享库)】揭开链接库的神秘面纱:手把手教你制作静态链接库与动态链接库

前言 不管是在 Windows 下开发&#xff0c;还是在 Linux 下开发&#xff0c;我们都会经常性的使用一些库文件&#xff0c;这些库文件的特点就是&#xff0c;我们可以看到接口的原型并通过这些接口来调用这个函数的功能&#xff0c;但是我们无法查看这个功能的实现。这就是库文…

静态链接库(.lib)和动态链接库(.dll)的使用

静态链接库(.lib)和动态链接库(.dll)的使用 文章目录 静态链接库(.lib)和动态链接库(.dll)的使用一、静态链接库1. 静态链接库概述2. 创建静态链接库3. 调用静态链接库 二、动态链接库(dynamic linking library)1. 动态链接库概述2. 创建动态链接库并导出函数导出函数两种方式1…

静态链接库

库 库的存在&#xff0c;大大方便了我们进行编程。因为有了库&#xff0c;我们不必再从0开始&#xff0c;例如我们大多数人C语言写的第一个程序Hello World!都是用了库函数。以printf为例&#xff0c;我们只需要在程序源代码中包含<stdio.h>这个头文件之后&#xff0c;就…

史上最全Java类型转换

讲类型转换之前&#xff0c;让我来贴张表 基本数据类型的表示范围 类型 长度 表示范围默认值byte8b-128&#xff5e;1270short16b-32768&#xff5e;327670int32b-21147483648&#xff5e;21474836470long64b-9223372036 854 775 808&#xff5e;9223372036 8547758070Lfloat3…

Java:类型转换

public class Demo04 {public static void main(String[] args) {//低--------------------------> 高// byte,short,char->int->long->float->doubleint i 128;byte b (byte) i ;//内存溢出//强制转换 &#xff08;类型&#xff09;变量名 高--低//自动转换…

java强转规则_java类型转换及其规则介绍

一、自动类型转换 整型、实型(常量)、字符型数据可以混合运算。运算中&#xff0c;不同类型的数据先转化为同一类型&#xff0c;然后进行运算。 数据类型转换必须满足如下规则&#xff1a; 1、不能对boolean类型进行类型转换。 2、不能把对象类型转换成不相关类的对象。 3、在把…

Sql-Java类型转换

Mysql-Java字段类型转换 mysql类型名大小用途对应Java类char0-255 bytes定长字符串 &#xff08;姓名、性别、学号&#xff09;Stringvarchar0-65535 bytes变长字符串&#xff08;比上面更长一点的那种&#xff09;Stringtinytext0-255 bytes比较短的那种文本数据&#xff08;…

JAVA类型转换及变量详解

类型转换 由于java是强类型语言&#xff0c;所以要进行有些运算的时候&#xff0c;需要用到类型转换。 byte&#xff08;1个字节&#xff09;,short&#xff08;2个字节&#xff09;,char&#xff08;2个字节&#xff09;----->int&#xff08;4个字节&#xff09;---->…

Java类型转换(自动类型转换+强制类型转换)

一、 自动类型转换(隐式类型转换) 整型、实型(常量)、字符型数据可以混合运算。运算中,不同类型的数据先转化为同一类型,然后进行运算。自动转换从低级到高级。 自动转换有以下规律: 1、小的类型自动转化为大的类型 2、整数类型可以自动转化为浮点类型,可能会产生舍入误…

Java的类型转换

需要类型转换的原因:因为Java是强类型的语言&#xff0c;所以有时可能要进行跨类型的运算&#xff0c;这就需要先进行类型转换&#xff0c;再进行运算。 类型转换分为&#xff1a; 强制类型转换(由高-->低时使用)&#xff0c;自动类型转换/ 隐式类型转换(由低-->高时使用…

java中的类型转换

java的基本数据类型 1.数值型&#xff1a;byte&#xff0c;short&#xff0c;int&#xff0c;long&#xff0c;float&#xff0c;double 2.字符型&#xff1a;char 3.布尔型&#xff1a;boolean 数据类型占据字节数byte1个字节short2个字节int4个字节long8个字节float4个字节…

Java中各种类型的转化

目录 一.Integer和int之间的类型转化 1.自动装箱 2.构造器方法 3.Integer.valueOf(int i) 二.Integer和String之间的类型转换 1.String转换为Integer 1.Integer.parseInt(String s) ​编辑 2.Integer.valueOf(String s) 2.Integer转换为String 1.Integer.toString() …

【JAVA】Java中的类型转换

目录 1.自动类型转换&#xff08;隐式转换&#xff0c;小类型转换为大类型&#xff09; 2.强制类型转换&#xff08;显示转换&#xff0c;大类型转换为小类型&#xff09; 3.小于4字节的类型转换问题 3.1 byte<->int 3.2 char<->int 3.3 String<->int …

Java 类型转换

一、自动类型转换(隐式类型转换) 整型、实型(常量)、字符型数据可以混合运算。不同类型的数据先转化为同类型再进行运算 自动转换按从低级到高级顺序: char ↓ Byte→short→int→long---›float→double 自动转换有以下规律&#xff1a; 小的类型自动转化为大的类型 整数…

java类型转换

文章目录 1、什么是类型转换&#xff1f; 2、掌握常见数据类型的范围大小 3、自动类型转换 3.1 int转换为double 3.2 char转换为int类型 4、强制类型转换 4.1、强制类型转换格式 5、注意事项 1、什么是类型转换&#xff1f; 在java中类型转换是一个非常重要的知识点。因…

java中常见类型的转换以及方法总结

1.char、String、int类型之间的转换 1.1 char和String的区别 char是表示的是字符&#xff0c;定义的时候用单引号&#xff0c;只能存储一个字符。例如; char‘d’. String表示的是字符串&#xff0c;定义的时候用双引号&#xff0c;可以存储一个或者多个字符。例如&#xff1…