Windows 动态链接库DLL使用
转载:https://blog.csdn.net/heyabo/article/details/8721611
转载:https://www.cnblogs.com/jin521/p/5598529.html
一、概念
DLL:Dynamic Link Library,即动态链接库,这种库包含了可由多个程序同时使用的代码和数据。
它是microsoft在windows操作系统中实现共享函数库概念的一种实现方式。其中windows中 一些作为DLL实现的文件有:
- ActiveX控件(.ocx)文件:如windows上的日历控件。
- 控制面板(.cpl)文件:控制面板中的每一项都是一个专用的DLL。
- 设备驱动程序(.drv)文件:如控制打印到打印机的打印机驱动程序。
二、由来
DLL最初用于节约应用程序所需要的磁盘和内存空间。早前,在传统的非共享库中,一部分代码简单地附加到调用的程序中。如果两个程序同时调用同一个子程序,就会出现两份那段代码。相反,许多应用共享的代码能够切分到一个DLL中,在硬盘上存为一个文档,在内存中只需使用一个实例。
三、DLL的优缺点
优点:
(1)节省内存和代码重用:当多个程序使用同一个函数库时,DLL可以减少在磁盘和物理内存中加载代码的重复量,且有助于代码的重用。
(2)模块化:DLL有助于促进模块式程序开发。模块化允许仅仅更改几个应用程序共享使用的一个DLL中的代码和数据而不需要更改应用程序自身。这种模块话的基本形式允许如Microsoft Office、Microsoft Visual Studio、甚至windows自身这样大的应用程序 使用较为紧凑的补丁和服务包。
缺点:
DLL Hell:即DLL地狱,指几个应用程序在使用同一个共享的DLL库时发生版本冲突。
究其原因,八个字:成也共用,败也共用。因为DLL Hell正是由于动态链接库可与其他程序共用函数、资源所导致。
主要有两种情况:
设想这样一个场景:程序A会使用1.0版本的动态链接库X,则在程序A安装到系统时,会同时安装该1.0版本的动态链接库X。假设另一个程序B也会使用到动态链接库X,那么程序B直接复制到硬盘中即可正常运行,因为动态链接库已经存在于系统中。然而有一天,另一程序C也要使用动态链接库X,但是由于程序C开发的时间较晚,其需要较新版本---2.0版本的动态链接库X。则在程序C被安装到系统时,2.0版本的动态链接库X 也必须随之安装到系统中,此时系统中1.0版本的动态链接库将被2.0版本所取代(替换)。
情况1:新版本的动态链接库不兼容旧版本。如,A何B需要X所提供的功能,在升级到2.0后,新版本的X竟然把此功能取消了(很难想象吧,呵呵但有时候就是如此....)。则此时虽然C能正常运行,但A和B均无法工作了。
情况2:新版本的动态链接库兼容旧版本,但是存在一个bug。
可看下面的例子(仅仅为了说明问题):
// X1.0 version
void func(int count)
{
if(count < )
count = ;
....
} // X2.0 version
void func(int count)
{
//负数处理被移除!
...
}
一旦出现count为负数的情况,则程序A在新版本的处理下就会有问题。
解决办法:Side-by-side Assembly,是windows Xp以及以上系统解决动态链接库版本冲突所使用的技术,重点在于编译程序时,由VS生成一个manifest文件,指明当前应用程序所使用的动态链接库版本号;发布程序时需同时发布该manifest文件,供客户计算机上的DLL Loader根据manifest加载适当版本的DLL,若不发布该项manifest,客户机则按默认版本加载DLL。下图为其典型的场景:
四、DLL与lib的关系
咋一看:lib是静态链接库;DLL是动态链接库,一个编译时提供;一个运行时提供,完了。
其实没那么简单!lib也有静态lib和动态lib之分。
静态lib:它将导出声明(后面会讲)和实现均放到lib中,编译后所有代码都嵌入到宿主程序中去。
动态lib:相当于一个h文件,它是对实现部分(.DLL)的导出部分的声明。编译后只是将导出声明部分编译到宿主程序中,运行时需要相应的DLL文件的支持,否则无法工作。当生成一个新的DLL时,也会有配套的lib产生(即二者需一起分发),此时的lib即为动态lib(后面会有还有实验)。
五、如何生成一个DLL
在VS2012开发环境下,打开File\New\Project选项,可以选择Win32 Dynamic-Link Library或MFC AppWizard【dll】来以不同的方式创建Non-MFC DLL、Regular DLL、Extension DLL等不同种类的动态链接库。下面以选择Win32 Dynamic-Link Library方式来创建一个DLL(实现加法运算)
2、分别添加头文件(.h)和源文件(.cpp)
// mydll.h file
extern "C" _declspec(dllexport) int add(int a, int b); //mydll.cpp file
#include "mydll.h"
int add(int a, int b) //该DLL需要导出的函数功能:加法
{
return a + b;
}
说明:
(1)前面的 extern “C” 告诉编译器函数可以在本模块或其他模块中使用,其中“C”表明需按照C语言方式编译和连接它,因为C++编译时,会对函数名进行修饰,用于实现函数重载,而C里面没有这个功能,所以需要用extern "C"在头文件进行声明的时候加以区分,以便链接时能进行正确地函数名查找。
(2)_declspec(dllexport)为导出函数关键字,意为需从DLL中导出该函数,以便使用
3、编译连接
在进行编译连接后会在Debug目录下找到DLL文件和对应的lib文件
六、如何调用一个DLL
下面实现两种调用方式:单独.dll 和.h + .lib + .dll结合
注:需把对应的 .dll 文件以及.lib 文件和.h文件(结合方式时)拷贝至调用的程序目录下
(1)单纯使用.dll
#include<wtypes.h>
#include <winbase.h>
#include <iostream>
_declspec(dllimport) int Add(int a, int b); //导入声明,亦可以不加,如果加上可加快程序运行 typedef int(*pAdd)(int a,int b); int main()
{ HINSTANCE hDLL;
pAdd Add;
hDLL=LoadLibrary(L"mydll.dll"); //加载 DLL文件
if(hDLL == NULL)std::cout<<"Error!!!\n";
Add=(pAdd)GetProcAddress(hDLL,"add"); //取DLL中的函数地址,以备调用 int a =Add(,);
std::cout<<"a: "<<a<<std::endl; FreeLibrary(hDLL);
return ;
}
输出结果:
(2).h + .lib + .dll 结合方式
#include<wtypes.h>
#include <winbase.h>
#include <iostream>#include "../MyDll/mydll.h"
#pragma comment(lib,"mydll.lib") //将mydll.lib库文件连接到目标文件中(即本工程)
extern "C"_declspec(dllimport) int add(int a,int b);
int main()
{ int a =add(,);
std::cout<<"a: "<<a<<std::endl; return ;
}
此时如果去掉 .dll 文件(即只有.lib 和 .h文件),则会出错:
Windows 动态链接库DLL使用的更多相关文章
- Golang编写Windows动态链接库(DLL)及C调用范例
一.准备. 1.GoLang在1.10版本之后开始支持编译windows动态链接库,可以打开命令行工具使用go version 查看自己的go版本. 2.你的电脑上需要gcc,如果没有的话[点击这里] ...
- Windows动态链接库DLL
1.什么是DLLDLL,即动态链接库,是包含若干个函数的库文件,可供其他程序运行时调用. 2.DLL的优缺点优点:代码重用,可供多个程序同时调用 缺点:易发生版本冲突当新版本的动态链接库不兼容旧版本时 ...
- Windows Phone 8加载外部动态链接库DLL(非安装包内的)
Windows Phone 8加载外部动态链接库DLL(非安装包内的) 在<动态加载与插件化>中大概介绍了下,wp8加载非安装包的下动态链接库,这次详细梳理下. 加载外部DLL主要的原理: ...
- Windows动态链接库:dll与exe相互调用问题
本文回顾学习一下Windows动态链接库:dll与exe相互调用问题.一般滴,exe用来调用dll中的类或函数,但是dll中也可以调用exe中的类或函数,本文做一些尝试总结. dll程序: Calcu ...
- VC++动态链接库(DLL)编程深入浅出(zz)
VC++动态链接库(DLL)编程深入浅出(zz) 1.概论 先来阐述一下DLL(Dynamic Linkable Library)的概念,你可以简单的把DLL看成一种仓库,它提供给你一些可以直接拿来用 ...
- VS2010编写动态链接库DLL及单元测试用例,调用DLL测试正确性
转自:http://blog.csdn.net/testcs_dn/article/details/27237509 本文将创建一个简单的动态链接库,并编写一个控制台应用程序使用该动态链接库,该动态链 ...
- delphi 2010 动态链接库DLL断点调试
DELPHI 2010 动态链接库DLL断点调试 马根峰 (广东联合电子服务股份有限公司,广州 510300) 摘要:本文详细介绍了Delphi 2010中的动态链接库DLL断点调试技术 关键词:DE ...
- MinGW gcc 生成动态链接库 dll 的一些问题汇总 (补充)
我以前写过一个小短文,介绍MinGW gcc 生成动态链接库 dll 的一些问题.当时写的并不全面.近期又遇到写新的问题.这里记录一下,做个补充. 通常情况下,dll 中的函数假设採用 _stdcal ...
- 动态链接库dll,静态链接库lib, 导入库lib
转载地址:http://www.cnblogs.com/chio/archive/2008/08/05/1261296.html 目前以lib后缀的库有两种,一种为静态链接库(Static Libar ...
随机推荐
- Unable to update the EntitySet 'T_JsAPI' because it has a DefiningQuery and no <InsertFunction> element exists in the <ModificationFunctionMapping> element to support the current operation.
前几天使用EF6的Db First模式改造了支付中心的数据访问层,废弃了ado.net. 同时,使用T4把实体类生成到了model层的PO目录下. 今天在db里新建了一张表,在edmx文件里更新模型( ...
- ####### Scripts Summary #######
Scripts Summary Version: 1.0.1 issueDate: 2017-11-11 modifiedDate: 2017-11-28 0.configuration 1.oper ...
- antlr安装
安装java环境,环境变量设置如下: ANTLR 简介 ANTLR—Another Tool for Language Recognition,Antlr 本身是使用 Java 开发的,它为包括Jav ...
- 49.CSS--- 特殊css3效果展示
1.设置多行文本超出显示省略号<div class="caption"> <p>显示超过两行就显示省略号,其余隐藏,隐藏不了的情况下给这个模块添加一个高度和 ...
- C# 对数据库操作的帮助类SQLHelper.cs
using System; using System.Collections.Generic; using System.Configuration; using System.Data; using ...
- docker-php-ext-install.md(https://gist.github.com/giansalex/2776a4206666d940d014792ab4700d80)
```bash RUN apt update RUN apt upgrade -y RUN apt install -y apt-utils RUN a2enmod rewrite RUN apt i ...
- “编程利器”:VSCode
原先一直使用sublime text3,并且认为它是很好的编程利器. 但最近写代码时,发现很多代码还是提示的不够完整.我们知道,当代码名字很长时,还没有提醒,这是非常苦恼的一件事!同时它的调试功能也不 ...
- yii2 modules模块配置指南
在Yii2 中模块是可以无限级嵌套的,也就是说,模块可以包含另一个包含模块的模块,我们称前者为父模块,后者为子模块, 子模块必须在父模块的yiibaseModule::modules属性中申明,例如: ...
- html5-文件的基本格式
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8&qu ...
- Properties (25)
1.Properties 没有泛型.也是哈希表集合,无序集合.{a=1,b=2,c=3} 2. 读取文件中的数据,并保存到集合 (Properties方法:stringPropertyName ...