动态链接库DLL

不使用时不会有任何作用,只有在其他模块调用动态链接库中的函数时,它才发挥作用。

一、静态库与动态库

1、静态库

函数和数据被编译进一个二进制文件(.LIB),编译时,会将其组合起来创建最终

的可执行文件(.exe文件),当发布产品时,只需要发布这个可执行文件,并不需要发

布被使用的静态库。

2、动态库

在使用动态库的时候,往往提供两个文件:一个引入库(.Lib)文件和一个DLL(.dll)

文件。

引入库文件(.lib),包含该DLL导出的函数和变量的符号名,而.dll文件包含该Dll实际

的函数和数据,

在使用动态库的情况下,在编译链接可执行文件时(生成.exe文件),只需要链接该DLL

的引入库文件(.Lib),直到可执行程序运行时(运行.exe),才去加载所需的DLL。

注:应用程序如果想要访问某个DLL中的函数,那么该函数必须是已经被导出的函数。

Dumpbin  查看DLL中有哪些导出函数。

进入到.dll所在目录,输入:dumpbin -exports  **.dll

二、动态链接库的加载:隐式链接、显式加载

为了让DLL导出一些函数,需要在每一个将要被导出的函数前面添加标识符:

_declspce(dllexport),

注:

.Lib :引入库文件(保存的是.dll中导出的函数和变量的符号名)

.exp:输入库文件

.dll:存放是的导出和非导出的函数的源代码。

名字改编:在编译链接时,C++会按照自己的规则篡改函数的名称

1、隐式链接方式加载DLL(在别的项目中使用编写的.dll文件中的函数)

为了编译成功:需要将.Lib文件加入到当前工程工作目录,可成功生成.exe

为了运行成功:需要将.dll文件加入到当前工作目录,可使.exe成功运行。

当用到动态链接库中的函数时,需要加载它们(搜索.dll并加载到内存中)

搜索路径:1、程序的执行目录

2、当前目录

3、系统目录

4、path环境变量中所列出的路径

注:Depends工具

查看一个可执行模块依赖的动态链接库。

在引用以后,如果使用到dll中的函数时,声明时需要用到_declspec(dllimport) 声明为

为外部函数,表示函数是从动态链接库中引入的,当然也可以用extern。

不过与extern关键字相比,使用_declspce(dllimport),编译器可以生成运行效率更高的

代码。

如果像普通的#include “.h”一样使用dll库的函数,可以为.dll程序中添加一个“.h”文

件内部放函数的声明,然后在.dll的 “cpp”文件中放函数的实现。

然后在发布dll的同时将.Lib,.dll,.h文件一起提供。在需要使用到的地方#include “.h”

文件就可以使用了。

当然头文件的写法需要注意:

如:DLL1.h

#ifdef DLL1_API

#else

#define DLL1_API  _declspec(dllimport) //关键

#endif

DLL1_API int add(int a,int b);

DLL1_API int substract(int a,int b);

Dll1.cpp

#define DLL1_API  _declspec(dllexport) //关键

#include “DLL1.h”

//实现代码

三、从DLL中导出C++类

如:在刚刚的DLL1.H文件中添加

class DLL1_API Point

{

Public:

Void output (int x,int y);

};

为了从动态链接库中导出一个类,只需要在class关键字和类名之前加入 导入/导出

标识符,就可以导出整个类了。

注:权限问题仍与原来的一样,public private protected.

如果采用隐式链接方式加载DLL,一旦DLL更新了,如果要使用新,一定要将新的文件复

制到你所在的工作目录。

也可以只导出类中的某个函数,把class后的关键字去掉,在函数前面加入导入导出

修饰符。

注:这两种导出的访问方式是没有区别的,都是先构造该类的一个对象,然后利用该对象访问该类导出的成员函数。

四、解决名字改编问题

编译器在生成DLL时,会对导出的函数进行名字改编,(而不同的编译器使用的改编规

则不一样)。如用C语言编写的程序访问调用C++编写的dll中的函数,就会出现问题。

鉴于以上原因:希望动态链接库文件在编译时,导出函数的名称不要发生改变。

为了实现:在定义导入/导出 函数时,加上extern “C”

可使用

extern  “C”//注意这个C是大写

{

//函数声明。

}

也可以在_declspec前加上extern “C”

注:这种方法只能用于导出全局函数这种情况,不能用于导出类的成员函数。

1、如果导出函数的调用约定发生了改变,那么即使使用了限定符,extern “C”

,该函数的名字仍会发生改编,这种情况下,可以通过一个称为模块定义文件

(DEF)的方式来解决名字改编问题。

在生成DLL工程的目录中,添加一个 .def文件(自创建),并在其中添加如下代码:

LIBRARY dll_name

EXPORTS

函数名称1

....2=函数名称2

....3

注:dll_name指定动态链接库的内部名称(必须与生成的动态链接库的名称匹配)

EXPORTS下面指定的是:表面DLL导出的函数,以及为这些导出函数指定的符号名,

常用的使用方法:
1、如果名称一致,会以原名称导出

2、如果前后名称不一致

Entryname=internalname  //导出后的名称=导出前的名称。

如:

Add

Sub

更多方法百度EXPORT的使用方法。

动态链接库 DLL的更多相关文章

  1. 编译可供C#调用的C/C++动态链接库dll文件

    编译可供C#调用的C/C++动态链接库dll文件,C语言控制台应用程序,探索生成dll过程 由于项目需求,需要公司另一个团队提供相关算法支持,是用C语言编译好的dll库提供给我们进行调用. 但是拿到d ...

  2. VC++动态链接库(DLL)编程深入浅出(zz)

    VC++动态链接库(DLL)编程深入浅出(zz) 1.概论 先来阐述一下DLL(Dynamic Linkable Library)的概念,你可以简单的把DLL看成一种仓库,它提供给你一些可以直接拿来用 ...

  3. VS2010编写动态链接库DLL及单元测试用例,调用DLL测试正确性

    转自:http://blog.csdn.net/testcs_dn/article/details/27237509 本文将创建一个简单的动态链接库,并编写一个控制台应用程序使用该动态链接库,该动态链 ...

  4. 无法加载 DLL“rasapi32.dll”: 动态链接库(DLL)初始化例程失败。

    无法加载 DLL“rasapi32.dll”: 动态链接库(DLL)初始化例程失败. 在Asp.Net项目中使用WebClient或HttpWebRequest时出现以上错误 解决方案:把以下代码放在 ...

  5. delphi 2010 动态链接库DLL断点调试

    DELPHI 2010 动态链接库DLL断点调试 马根峰 (广东联合电子服务股份有限公司,广州 510300) 摘要:本文详细介绍了Delphi 2010中的动态链接库DLL断点调试技术 关键词:DE ...

  6. MinGW gcc 生成动态链接库 dll 的一些问题汇总 (补充)

    我以前写过一个小短文,介绍MinGW gcc 生成动态链接库 dll 的一些问题.当时写的并不全面.近期又遇到写新的问题.这里记录一下,做个补充. 通常情况下,dll 中的函数假设採用 _stdcal ...

  7. 动态链接库dll,静态链接库lib, 导入库lib

    转载地址:http://www.cnblogs.com/chio/archive/2008/08/05/1261296.html 目前以lib后缀的库有两种,一种为静态链接库(Static Libar ...

  8. 动态链接库dll的 静态加载 与 动态加载

    dll 两种链接方式  : 动态链接和静态链接(链接亦称加载) 动态链接是指在生成可执行文件时不将所有程序用到的函数链接到一个文件,因为有许多函数在操作系统带的dll文件中,当程序运行时直接从操作系统 ...

  9. VS2010编写动态链接库DLL和单元测试,转让DLL测试的正确性

    本文将创建一个简单的动态库-link,谱写控制台应用程序使用该动态链接库,该动态链接库为"JAVA调用动态链接库DLL之JNative学习"中使用的DLL,仅仅是项目及文件名不同. ...

随机推荐

  1. hadoop笔记之Hive的数据存储(分区表)

    Hive的数据存储(分区表) Hive的数据存储(分区表) 分区表 Partition对应于数据库的Partition列的密集索引 在Hive中,表中的一个Partition对应于表下的一个目录,所有 ...

  2. jquery插件anccordion

    (function(){ $.fn.YAccordion=function(options){ var settings={ trigger:'click', speed:300, }; if(opt ...

  3. Why Study JavaScript?

    JavaScript is one of the 3 languages all web developers must learn: 1. HTML to define the content of ...

  4. requirejs + vue 项目搭建

    以前都是支持 司徒正美 的,毕竟咱们也是跟着 司徒正美 一起走进了前端的世界.所以一般MVVM都是用avalon的,当然也是考虑到项目需要支持IE6,7,8的考虑.当然在用的时候也有一些小坑和bug, ...

  5. git Feature分支

    Feature分支 软件开发中,总有无穷无尽的新的功能要不断添加进来. 添加一个新功能时,你肯定不希望因为一些实验性质的代码,把主分支搞乱了,所以,每添加一个新功能,最好新建一个feature分支,在 ...

  6. 继承过程中对函数中this的认识

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. struts漏洞修补过程之S2-016

    Struts漏洞修补过程之S2-016.邪恶的Struts再次现身,这一次是远程执行漏洞.官方建议立即升级到2.3.15.1.真希望这是最后一次漏洞修补.下面是升级步骤. 1.升级到struts2.3 ...

  8. poj 3680 Intervals(费用流)

    http://poj.org/problem?id=3680 巧妙的构图. 题目:给定N个区间(ai,bi)权值wi,求最大权和且每个点最多覆盖K次. 构图:将区间端点离散化,将第i个点连第i+1个点 ...

  9. Swift 闭包表达式

    闭包是功能性自包含模块,可以在代码中被传递和使用. Swift 中的闭包与 C 和 Objective-C 中的 blocks 以及其他一些编程语言中的 lambdas 比较相似. 闭包的形式主要有三 ...

  10. 1.Solution的Build、Rebuild和Clean

    大家好,我是原文,这篇随笔是对原文的翻译以及自己的体会. 做程序员没追求的话是永远找不到女朋友的,当然有追求也找不到,这个先不提,好在有追求的时候我是充实而且开心的.现在我们的问题是,每天调试项目,在 ...