Windows下静态库和动态库的生成和调用

  • 一、简介
  • 二、生成静态链接库(.lib)和动态链接库(.dll)
  • 三、静态链接库的调用
  • 四、动态链接库的调用
    • 动态链接库的两种调用方式
      • 仅使用.dll文件
      • 使用.h+.dll+.lib文件

一、简介

为了提高代码的复用性,引入了库,库是一段可执行代码的二进制形式,可以被操作系统直接载入内存使用。一般分为动态库和静态库,在Windows操作系统中静态库是以 .lib 为后缀的文件,动态库是以 .dll 为后缀的文件。

C++程序编译以及调用库的过程如下:

可以看到库是在链接过程和目标文件一起打包最终生成可执行文件,另外可以看到静态库和动态库是编译型语言所特有的,对于非编译型语言例如python,在实现上有所不同。
以下是静态链接库和动态链接库的区别:

1. 静态链接库(.lib):在链接阶段,会将汇编生成的目标文件.o与引用到的库一起链接打包到可执行文件中,相当于在可执行文件中每个用到库的地方,都会插入一份库的代码,这样会增加最终生成的可执行文件的体积。
2. 动态链接库(.dll):在链接阶段,动态库并不会被插入到目标文件.o中,而是在.exe可执行文件运行时才会被加载到内存,然后被程序调用,这样能大大减小生成的可执行文件的体积,并且动态链接库被修改时,并不需要重新编译生成源代码。

二、生成静态链接库(.lib)和动态链接库(.dll)

  1. 首先使用vs2019新建空项目,命名选择存储位置。
  2. 在项目中新建空白 .h 头文件和 .cpp 源文件,如下:
  • .h 头文件输入以下代码:
// addnum.h
#ifndef __ADDNUM_H__
#define __ADDNUM_H__extern "C" {_declspec(dllexport) int AddTwoInt(int a, int b);
}
#endif // !__ADDNUM_H__
  • .cpp 源文件输入以下代码:
// addnum.cpp
#include "addnum.h"
int AddTwoInt(int a, int b)
{return a + b;
}
  • 其中.h 头文件中extern “C” 表示使用C语言方式生成链接库,而_declspec(dllexport)用于声明库函数,.cpp源文件是该函数的具体实现过程,AddTwoInt()函数的功能是计算两个整形数之和。
  1. 点击项目->属性->常规->配置类型,设置当前项目的生成类型。如下图:

    可以看到,这里可以选择生成的类型,如果要生成静态链接库,选择静态库,如果要生成动态链接库,选择动态库,选择之后点击确定即可。

  2. 点击生成,生成解决方案,然后就会在相应文件夹下生成库文件,如下:

  • 生成静态库(.lib)
  • 生成动态库(.dll)

    生成了对应的动态库和静态库之后,下面就可以编写源程序来调用库。

三、静态链接库的调用

相较于动态链接库,静态链接库的调用相对简单,我们只需要在调用函数中声明好静态库中的函数接口,即可完成调用。

  1. 首先还是使用vs2019新建一个空项目,然后在项目下新建 addnum.h 和 main.cpp 文件,其中addnum.h 文件是对库的函数接口的说明,main.cpp 调用库函数。代码分别为:
  • addnum.h文件:
// addnum.h
#ifndef __ADDNUM_H__
#define __ADDNUM_H__
extern "C" {_declspec(dllimport) int AddTwoInt(int a, int b);
}
#endif // !__ADDNUM_H__
  • main.cpp文件:
// main.cpp
#include <iostream>
#include "addnum.h"
using namespace std;
int main() {cout << AddTwoInt(7, 19) << endl;return 1;
}
  • addnum.h文件主要声明AddTwoInt()函数是从外部库导入的,main()函数调用AddTwoInt()函数计算"7+19"的结果。
  1. 将之前生成的libtest.lib静态链接库添加到项目的资源文件,完成后如下:
  2. 按Ctrl+F5或者点击调试->开始执行,运行源代码,得到结果如下:

    可以看到程序返回结果为26,说明调用成功。

四、动态链接库的调用

动态链接库的两种调用方式

相对于调用静态库,调用动态库的过程更加复杂。主要由两种方法:

  • 第一种方法是仅使用之前编译生成的.dll动态链接库文件,程序在运行时将库直接加载到内存中,获取函数的入口地址,然后利用函数指针直接调用。
  • 第二种方法是使用编译动态库过程中产生的静态库,这个静态库是系统自动生成的,其内部并不包含函数接口,作用只是获得动态库的函数地址,使得可以像调用静态库一样调用动态库。

仅使用.dll文件

  1. 同样的,首先新建一个空项目,在项目中新建一个.cpp源文件以及将之前生成的.dll动态库文件添加到项目文件夹下以及项目中,如下:
  • main.cpp中的代码:
// main.cpp
#include <iostream>
#include <Windows.h>
using namespace std;typedef int (*pAddTwoInt)(int, int);     //对应的函数指针类型,指向AddTwoInt()函数在内存中的入口地址int main()
{HMODULE hdll;   //动态链接库的句柄hdll = LoadLibrary("libtest.dll");    //加载动态链接库,返回其句柄if (hdll == NULL){cout << "lib load failed!" << endl;return 1;}pAddTwoInt fAddTwoInt = (pAddTwoInt)GetProcAddress(hdll, "AddTwoInt");  //获取动态链接库中AddTwoInt()函数的入口地址cout << fAddTwoInt(7, 19) << endl;       //调用获取到的函数计算结果FreeLibrary(hdll);     //调用结束,在内存中释放动态库return 1;
}
  • 运行,得到结果如下:

使用.h+.dll+.lib文件

这种方法调用需要使用编译生成动态链接库时自动生成的静态库,调用方法类似调用静态库,但是本质上却是使用的动态库。

  1. 同样的,首先新建一个空项目,在项目下添加addnum.h和main.cpp文件,然后将生成的动态库和静态库都复制到项目文件夹下,以及添加到项目,如下:
  2. 由于这里调用动态库的方法和调用静态库一样,因此此处addnum.h和main.cpp的内容页数一样的,如下:
  • addnum.h文件:
// addnum.h
#ifndef __ADDNUM_H__
#define __ADDNUM_H__
extern "C" {_declspec(dllexport) int AddTwoInt(int a, int b);
}
#endif // !__ADDNUM_H__
  • main.cpp文件:
// main.cpp
#include <iostream>
#include "addnum.h"
using namespace std;int main()
{cout << AddTwoInt(7, 19) << endl;return 1;
}
  1. 运行,结果如下:

    也成功的得到了结果。

Windows下动态链接库和静态链接库的生成以及调用相关推荐

  1. Linux下Makefile中动态链接库和静态链接库的生成与调用

    背景:写这篇博客的原因是:最近在搞嵌入式,需要交叉编译opencv库文件,自己写Makefile,通过arm-linux-g++编译.链接.生成可执行文件,从而实现了移植的过程.平台是Toradex的 ...

  2. c++动态链接库及静态链接库的生成与使用

    c++动态链接库及静态链接库的生成与使用 1,新建控制台工程xdltest,改属性-配置属性-常规-配置类型为 动态库.dll或静态库.lib 2,打开工程后添加 dltest.h, dltest.c ...

  3. Linux下动态链接库与静态链接库(编写、编译)

    这里写目录标题 函数库的概念 动态库的编译 静态库的编译 动态库相对于静态库的优点和缺点 优点 缺点 函数库的概念 函数库一般分为静态库和动态库两种. 静态库: 是指编译链接时,把库文件的代码全部加入 ...

  4. windows 调用linux .a lib,动态链接库及静态链接库(windows下的.dll .lib和linux下的.so .a)...

    动态链接库及静态链接库(windows下的.dll .lib和linux下的.so .a) 库有动态与静态两种,动态通常用.so为后缀,静态用.a为后缀.例如:libhello.so libhello ...

  5. 动态链接库与静态链接库

    动态链接库与静态链接库 首先纠正所谓"静态连接就是把需要的库函数放进你的exe之中"的说法.在真实世界中,有三个概念:Use   static   libary,   static ...

  6. 关于动态链接库和静态链接库

    关于动态链接库和静态链接库 库是写好的现有的,成熟的,可以复用的代码.现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常. 本质上来说库是一种可执行代码的二 ...

  7. mingw编译opencv动态链接库和静态链接库及使用方法

    前言 我一直不知道编译的过程以及cmake, make 这些工具是干什么的,所有抽时间研究了一下. 简单来说就是 cmake 是根据 CMakeLists.txt 用来生成 makefile文件的.而 ...

  8. linux 生成和使用动态链接库和静态链接库的Makefile编写

    引用 Jesse Rei 的 linux 生成和使用动态链接库和静态链接库的Makefile编写 生成和使用动态链接库和静态链接库的Makefile编写 1. 概述 介绍linux下生成和使用动态链接 ...

  9. 动态链接库和静态链接库的区别

    两种库: 一种是LIB包含了函数所在的DLL文件和文件中函数位置的信息(入口),代码由运行时加载在进程空间中的DLL提供,称为动态链接库dynamic link library. 一种是LIB包含函数 ...

最新文章

  1. Linux shell 学习笔记(15)— shell 正则表达式
  2. ecshop后台实现用ajax动态修改/更新用户评论的时间
  3. yum与rpm的使用
  4. 华容道游戏开发--android小组
  5. 牛客题霸 [ 有重复项数字的所有排列] C++题解/答案
  6. 201609-5 祭坛
  7. python动态添加类方法_Python 动态添加类方法
  8. LeNet-5 卷积神经网络
  9. Node编写API接口,ajax实现增删改查
  10. 更新小红伞antivirus失败:生成更新结构失败。更新库生成错误 556
  11. css中属性选择器用法总结c
  12. const 成员函数
  13. 各种PLC解密软件集合
  14. 【win10】配置系统未初始化
  15. 使用深度图重建世界坐标
  16. 搜狗站长html标签验证,各大搜索引擎站长验证以及百度统计代码配置
  17. java smtp.126.com_java开发_STMP邮箱客户端_发送邮件
  18. 团队管理---管理经典理论
  19. 【入门】QQ聊天机器人--HelloWorld篇
  20. django 设置媒体url_django-文件上传Media url的配置

热门文章

  1. 高校实验室应该怎样建设(实验室建设规划)
  2. BlenderGIS生成三维地图白模
  3. solarlunar库, 阴历,阳历日期及转换库
  4. ubuntu:自动加载第三方设备驱动
  5. win7如何看计算机配置,Win7怎么看电脑配置?查看电脑配置的方法
  6. 面向过程与面向对象——编程思想的演变
  7. python写的推箱子小游戏
  8. 《机器学习》慕课版课后习题-第13章
  9. Django 连接redis
  10. 报废计算机设备要交税吗,电脑报废处理如何税务处理