封装动态库dll与静态库lib(原理及简单实例)

开发流程

https://www.runoob.com/w3cnote/cpp-static-library-and-dynamic-library.html

文章目录

  • 开发流程
    • lib、dll介绍
      • 静态库:
      • 动态库:
    • 生成和使用静态库lib
    • 生成和使用动态库
      • 实现流程(隐式调用)
      • 实现流程(显式调用)

lib、dll介绍

静态库:

在链接步骤中,连接器将从库文件取得所需的代码,复制到生成的可执行文件exe中,这种库称为静态库,其特点是可执行文件中包含了库代码的一份完整拷贝;缺点就是被多次使用就会有多份冗余拷贝。即静态库中的指令都全部被直接包含在最终生成的 EXE 文件中了。在vs中新建生成静态库的工程,编译生成成功后,只产生一个.lib文件

lib=>exe

静态编译\动态编译

静态库lib编译的时候全部嵌入exe,导致exe会很大

动态库:

动态链接库是一个包含可由多个程序同时使用的代码和数据的库,DLL不是可执行文件。动态链接提供了一种方法,使进程可以调用不属于其可执行代码的函数。函数的可执行代码位于一个 DLL 中,该 DLL 包含一个或多个已被编译、链接并与使用它们的进程分开存储的函数。在vs中新建生成动态库的工程,编译成功后,产生一个.lib文件和一个.dll文件。

动态库就是动态加载

photoshop.exe 113MB

动态加载,用的时候链接一下

软件升级,连一下网络,替换一下dll

静态库和动态库中的lib有什么区别呢?

1、静态库中的lib:该LIB包含函数代码本身(即包括函数的索引,也包括实现),在编译时直接将代码加入程序当中

2、动态库中的lib:该LIB包含了函数所在的DLL文件和文件中函数位置的信息(索引),函数实现代码由运行时加载在进程空间中的DLL提供

总之,lib是编译时用到的,dll是运行时用到的。如果要完成源代码的编译,只需要lib;如果要使动态链接的程序运行起来,只需要dll

生成和使用静态库lib

​ 1、建立win32项目、空项目、lib文件

  • 建立testlib.h文件

    #ifndef TETLIB_H
    #define TESTLB_H
    //防止头文件重复包含
    //条件编译指令
    
    //加减乘除,此处声明想用函数
    int add(int a,int b);
    int Cheng(int a, int b);
    
    #endif
    
  • 建立testlib.cpp文件

    #include "testlib.h"
    
    //加减乘除
    int add(int a, int b)
    {
    	return a + b;
    }
    
    int Cheng(int a, int b)
    {
    	return a*b;
    }
    
    

    2、建立win32控制台程序、空项目(最下面的取消勾选)、控制台程序

    #include 
    #include 
    #include "../testlib/testlib.h"               //包含静态库的头文件
    #pragma comment(lib, "testlib.lib")           //链接静态库
    
    int main()
    {
    	std::cout << "请输入两个整数,计算和" << std::endl;
    	int a, b;
    	std::cin >> a >> b;
    
    	//调用静态库
    	std::cout << add(a, b) << std::endl;
    	std::cout << Cheng(a, b) << std::endl;
    	return 0;
    }
    

    1、包含静态库头文件

    2、在连接器-常规-附加库目录,包含lib — 相对路径==…\Debug与$(SolutionDir)Debug一样==

    3、#pragma comment(lib, “testlib.lib”) //链接静态库

生成和使用动态库

1、建立win32项目、空项目(不勾选安全开发周期)、dll

  • 建立testdll.h文件

    #ifndef TESDLL_H
    #define TESDLL_H
    
    //#ifdef和ifndef意思相反
    
    //条件编译指令    如果预处理命令中有_DLLAPI,便执行export输出,否则输入
    #ifdef _DLLAPI           //**本win32项目下预处理器加入_DLLAPI**//
    #define DLLAPI _declspec(dllexport)
    #else
    #define DLLAPI _declspec(dllimport)
    #endif
    
    //声明导出函数
    extern "C"  DLLAPI int  /*DLLAPI*/ add(int a, int b); 
    //按着C语言的方式编译,函数名称不变,配合Dependency Walker软件使用,可以很
    //直观看出来。
    
    #endif
    
  • 建立testdll.cpp文件

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

2、建立win32控制台程序、空项目、控制台程序

  • 建立test.cpp文件

    #include
    #include"../testdll/testdll.h"
    //#pragma comment(lib,"testdll.lib")//这不是真的静态库,隐式调用
    
    //导入,不叫导出
    DLLAPI int add(int a, int b);
    
    
    int main()
    {
    	int a, b;
    	std::cout << "请输入" << std::endl;
    	std::cin >> a >> b;
    
    	std::cout << add(a, b) << std::endl;
    
    	return 0;
    }
    

实现流程(隐式调用)

  • #include"…/testdll/testdll.h"的效果与在VC++目录-包含目录下添加效果一致
  • lib文件应在连接器-常规-附加库目录添加路径
  • #pragma comment(lib,“testdll.lib”) 的效果与在链接器-输入-附属依赖项里面加testdll.lib效果一致
  • ==dll的操作:==1、放到exe文件下

​ 2、编写出口和接口包含库.h输出测试文件.cpp接收

//导出
extern "C"  DLLAPI int  /*DLLAPI*/ add(int a, int b);
//导入,不叫导出
DLLAPI int add(int a, int b);
  • dll的操作另一种方式==(但是调用不会搞,调用好像有问题)==
建立模块组件 实际代码

实现流程(显式调用)

了解,一般不常用,需要.h和dll,不需要lib

你可能感兴趣的:(企业级封装动态库流程,c++)