动态链接库--靠谱

1.什么是动态链接库
动态链接库(Dynamic-Link Library)通常包含程序员自定义的变量和函数,可以在运行时动态链接到可执行文件中

2.动态库扩展名
Windows下是.dll,Linux下是.so

3.Windows系统动态链接库
Windows操作系统核心有三个动态链接库(Kernel32.dll、User32.dll、Gdi32.dll),这些动态链接库构成了Win32 API函数

4.动态链接库的优点
1)节省内存和代码重用:当应用程序使用动态链接时,多个应用程序可以共享磁盘上单个DLL副本

2)可扩展性:DLL文件与EXE文件独立,只要接口不变,升级程序只需更新DLL文件不需要重新编译应用程序

3)复用性:DLL的编制与具体的编程语言以及编译器无关,不同语言编写的程序只要按照函数调用约定就可以调用同一个DLL函数

5.动态链接库的缺点
DLL地狱(DLL HELL)

6.创建动态链接库
1)创建DLL项目

2)添加.h头文件和.cpp文件

和静态库的写法一样

在.cpp中:

#include "func.h"
#include "stdafx.h"
 
int SquareSum(int a, int b)
{
    return (a*a + b * b);
}
 
int SumSquare(int a, int b)
{
    return ((a + b)*(a*b));
}


在.h文件中:

#pragma once
 
int SquareSum(int a, int b);
 
int SumSquare(int a, int b);


 这种情况下,我们点击生成,发现的确生成了一个.dll文件,但是没有.lib文件,如果我们用Dependency打开这个.dll文件,发现这个动态库是一个空文件,里面什么函数也没有

3)使用extern “C” 和_declspec(dllexport)

在.cpp里面的每个函数前面添加:

extern "C" _declspec(dllexport)


 完整的就是:

#include "func.h"
#include "stdafx.h"
 
extern "C" _declspec(dllexport) int SquareSum(int a, int b)
{
    return (a*a + b * b);
}
 
extern "C" _declspec(dllexport) int SumSquare(int a, int b)
{
    return ((a + b)*(a*b));
}


这样就生成了.lib文件和.dll两个文件

自己在VS2017中测试只在函数实现的地方加了 extern "C" 和_declspec(dllexport),并没有在函数声明的地方添加它,得到了两个文件;也测试了在函数实现和声明的地方都添加它,得到了两个文件;但如果只在函数声明的地方添加它而不在函数实现的地方添加,这样便还是只得到了.dll文件而没有.lib文件

4)生成.lib和.dll文件

7.使用动态链接库
1)创建一个应用程序项目

2)编写程序在.cpp中:

#include <iostream>
using namespace std;
#include "func.h"
 
#pragma comment(lib,"DynamicLib32.lib")
 
int main()
{
    int a = 34;
    int b = 32;
    cout << SquareSum(a, b) << endl;
    cout << SumSquare(a, b) << endl;
 
    system("pause");
    return 0;
}


.h中(.h文件可以从生成dll项目中拷贝过来,但需要注意下面几点):

#pragma once
 
int SquareSum(int a, int b);
int SumSquare(int a, int b);



如果在.h中直接这样,便会编译错误:


处理办法,在函数声明的地方加上extern “C”

#pragma once
 
extern "C" int SquareSum(int a, int b);
 
extern "C" int SumSquare(int a, int b);


但是这样方法也不是最好的,建议加上_declspec(dllimport),虽然它可以省略,但它可以提示编译器这个函数是从外部dll中导入的,有利程序的编译:

#pragma once
 
extern "C" _declspec(dllimport) int SquareSum(int a, int b);
 
extern "C" _declspec(dllimport) int SumSquare(int a, int b);


如果是从dll项目中直接拷贝过来的.h头文件中是:extern "C" _declspec(dllexport),发现也会编译正确,但不建议这样,建议改成上面的形式,把export改成import

3)添加.lib文件,dll项目不仅会生成.dll文件也会生成一个“配套”的.lib文件,简单理解,这个文件记录了dll中函数的入口地址,所以要像静态库中的.lib文件一样,用同样的两种方式把它加到我们的项目中,具体方法看静态链接库的生成和使用

添加好后,直接运行会得到错误:

4)添加.dll文件。把.dll文件添加到项目的.exe同一个路径下

这时运行便会得到正确结果:

8.注意
1)可以修改.lib文件的文件名,只要在项目引用它时,使用它目前的名称,便可以正确运行,但不能改变.dll文件的名字,不然也会出现找不到.dll文件的错误

2).dll文件必须和.exe放在一起,.exe文件在哪里.dll文件也得在那里,两者“共存亡”,否则就会出现找不到.dll文件的错误

3)和静态库一样,.dll文件也要和应用程序的位数相对应,要么都是64位的,要么都是32位的,不可交叉使用,否则出现:

 
--------------------- 
作者:深山里的小白羊 
来源:CSDN 
原文:https://blog.csdn.net/qq_33757398/article/details/81545966 
版权声明:本文为博主原创文章,转载请附上博文链接!

Higher you climb, more view you will see.
原文地址:https://www.cnblogs.com/yyfighting/p/12500643.html