动态链接库:我们经常把常用的代码制作成一个可执行模块供其他可执行文件调用,这样的模块称为链接库,分为动态链接库和静态链接库。

对于静态链接库,LIB包含具体实现代码且会被包含进EXE中,导致文件过大,浪费磁盘和内存;

对于动态链接库,DLL不必被包含在最终的EXE中,EXE执行时可以动态地装载和卸载DLL文件。

导出函数

将函数声明为导出函数有两种方式:

1、 在函数声明上加上_declspec(dllexport):

如:extern "C" int__declspec(dllexport)add(int x, int y);

2、 在.def文件中声明:如:

; lib.def : 导出DLL函数

LIBRARY dllTest(dll名称可忽略,但需要和生成的名称一致)

EXPORTS

Add @ 1

以”;”开始的为注释行,上述例子表示:生成名为“dllTest”的动态链接库,导出其中的add函数,序号为1。该序号在函数调用时起作用:GetProcAddress ( hDll, MAKEINTRESOURCE ( n ))返回 def定义的第n个函数地址。

DLL调用

使用动态链接库的时,往往提供两个文件:引入库文件(LIB)和动态链接库(DLL)。引入库文件(LIB)包含动态连接库(DLL)所有导出的函数和变量的符号名和地址,动态连接库(DLL)包含实际的函数和数据。调用方式分为动态调用(显式链接)和静态调用(隐式链接)。

1、 静态调用(隐式链接)

由编译系统完成对DLL的加载和卸载。共需两步操作:

告诉编译器与DLL相对应的LIB文件所在的路径及文件名,如#pragma comment (lib,"dllTest.lib") ;

声明导入函数,如:extern "C" __declspec(dllimport)add(int x,int y)(若有导出函数声明的头文件可直接包含该.h文件);

2、 动态调用(显示链接)

使用Win32 API 函数LoadLibrary、GetProcAddress、FreeLibrary实现"DLL加载-DLL函数地址获取-DLL释放”。这种方法不需要LIB文件,只需要DLL文件即可,显式链接速度更快且更加灵活。

关于DLL放置路径:

使用显式链接,在函数LoadLibrary的参数中可以指定DLL文件的完整路径;如果不指定路径,或者进行隐式链接,Windows将遵循下面的搜索顺序来定位DLL:

(1)包含EXE文件的目录

(2)工程目录

(3)Windows系统目录

(4)Windows目录

(5)列在Path环境变量中的一系列目录

例:

1、 生成DLL

创建Win32控制台的DLL项目MyDll,新建mydll.h和mydll.cpp,源码如下:

//mydll.h文件
#ifndef _MYDLL_H
#define _MYDLL_H
extern "C" int __declspec(dllexport)add(int x, int y);
#endif
//mydll.cpp文件
#include "mydll.h"
int add(int x, int y)
{
return x + y;
}

编译(F7)生成MyDll.lib和MyDll.dll。(extern "C"指定导出函数为c链接,避免C/C++命名规则不同导致的函数名不一致)

2、 调用DLL

创建Win32控制台项目,新建test.cpp文件,源码如下:

动态调用:(将MyDll.dll拷贝至工程目录)

#include <stdio.h>
#include <windows.h>
typedef int(*lpAddFun)(int, int); //宏定义函数指针类型
int main(int argc, char *argv[])
{
HINSTANCE hDll = LoadLibrary("MyDll.dll");//加载DLL
if (hDll != NULL)
{
lpAddFun addFun = (lpAddFun)GetProcAddress(hDll, "add");//获取函数地址
if (addFun != NULL)
{
int result = addFun(2, 3);
printf("%d", result);
}
FreeLibrary(hDll);//卸载DLL
}
return 0;
}

静态调用:(将MyDll.dll和MyDll.lib拷贝至工程目录)

#pragma comment(lib,"MyDll.lib")
extern "C" __declspec(dllimport) int add(int x,int y);
#include <stdio.h>
int main(int argc, char* argv[])
{
int result = add(2,3);
printf("%d",result);
return 0;
}

有时DLL导出函数若很多,在静态调用时,为了避免逐个写出extern "C"__declspec(dllimport) function(),可以直接包含DLL头文件(若有的话)。对于DLL制作者来说,需要实现头文件中函数是导入还是导出的自动转换,这时可通过定义宏实现。在DLL工程中头文件作用为导出声明,在应用工程中该头文件为导出声明。这时,DLL工程MyDll源码如下:

//mydll.h文件
#ifndef _MYDLL_H
#define _MYDLL_H
#ifdef MYDLL_EXPORT
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endif
extern "C" MYDLL_API int add(int x, int y);
#endif
// mydll.cpp文件
#define MYDLL_EXPORT //只在DLL实现中定义此符号
#include "mydll.h"
int add(int x, int y)
{
return x + y;
}

静态调用:(将MyDll.dll,MyDll.lib, mydll.h拷贝至工程目录)

#pragma comment(lib,"MyDll.lib")
#include"mydll.h"
#include <stdio.h>
int main(int argc, char* argv[])
{
int result = add(2,3);
printf("%d",result);
return 0;
}

参考:

http://www.cnblogs.com/chio/archive/2007/11/03/948480.html#undefined

http://www.cnblogs.com/fangyukuan/archive/2010/06/20/1761464.html

http://www.cppblog.com/amazon/archive/2009/09/04/95318.html

版权声明:本文为博主原创文章,未经博主允许不得转载。

动态链接库(DLL) 分类: c/c++ 2015-01-04 23:30 423人阅读 评论(0) 收藏的更多相关文章

  1. HDU2680 Choose the best route 最短路 分类: ACM 2015-03-18 23:30 37人阅读 评论(0) 收藏

    Choose the best route Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  2. android开发之调试技巧 分类: android 学习笔记 2015-07-18 21:30 140人阅读 评论(0) 收藏

    我们都知道,android的调试打了断点之后运行时要使用debug as->android application 但是这样的运行效率非常低,那么我们有没有快速的方法呢? 当然有. 我们打完断点 ...

  3. HDU 1272 小希的迷宫(并查集) 分类: 并查集 2015-07-07 23:38 2人阅读 评论(0) 收藏

    Description 上次Gardon的迷宫城堡小希玩了很久(见Problem B),现在她也想设计一个迷宫让Gardon来走.但是她设计迷宫的思路不一样,首先她认为所有的通道都应该是双向连通的,就 ...

  4. MS SQL数据批量备份还原(适用于MS SQL 2005+) 分类: SQL Server 数据库 2015-03-10 14:32 103人阅读 评论(0) 收藏

    我们知道通过Sql代理,可以实现数据库的定时备份功能:当数据库里的数据库很多时,备份一个数据库需要建立对应的定时作业,相对来说比较麻烦: 还好,微软自带的osql工具,比较实用,通过在命令行里里输入命 ...

  5. NYOJ-289 苹果 289 AC(01背包) 分类: NYOJ 2014-01-01 21:30 178人阅读 评论(0) 收藏

    #include<stdio.h> #include<string.h> #define max(x,y) x>y?x:y struct apple { int c; i ...

  6. ubuntu14.04使用root用户登录桌面 分类: 学习笔记 linux ubuntu 2015-07-05 10:30 199人阅读 评论(0) 收藏

    ubuntu安装好之后,默认是不能用root用户登录桌面的,只能使用普通用户或者访客登录.怎样开启root用户登录桌面呢? 先用普通用户登录,然后切换到root用户,然后执行如下命令: vi /usr ...

  7. Matlab调用C程序 分类: Matlab c/c++ 2015-01-06 19:18 464人阅读 评论(0) 收藏

    Matlab是矩阵语言,如果运算可以用矩阵实现,其运算速度非常快.但若运算中涉及到大量循环,Matlab的速度令人难以忍受的.当必须使用for循环且找不到对应的矩阵运算来等效时,可以将耗时长的函数用C ...

  8. Mahout快速入门教程 分类: B10_计算机基础 2015-03-07 16:20 508人阅读 评论(0) 收藏

    Mahout 是一个很强大的数据挖掘工具,是一个分布式机器学习算法的集合,包括:被称为Taste的分布式协同过滤的实现.分类.聚类等.Mahout最大的优点就是基于hadoop实现,把很多以前运行于单 ...

  9. 各种排序算法的分析及java实现 分类: B10_计算机基础 2015-02-03 20:09 186人阅读 评论(0) 收藏

    转载自:http://www.cnblogs.com/liuling/p/2013-7-24-01.html 另可参考:http://gengning938.blog.163.com/blog/sta ...

随机推荐

  1. DICOM:再次剖析fo-dicom中DicomService的自己定义事件绑定

    题记: 趁着<从0到1>大火的热潮,最近又一次翻阅了一遍<从一到无穷大>(这样是不是感觉整个非负数轴就圆满了^_^). 尽管作为科普类书籍.可是里面的内容还是比較深奥,幸亏有作 ...

  2. Eclipse配置中文(汉化)

    1.首先打开网址:http://www.eclipse.org/babel/downloads.php 然后查看安装以及版本选择 关于安装存储库,去这里查看 我选的是最新的版本:oxygen 未FQ请 ...

  3. MySQL多实例配置(一)

    MySQL数据库的集中化运维,能够通过在一台MySQL数据库服务器上,部署多个MySQL实例.该功能是通过mysqld_multi来实现.mysqld_multi用于管理多个mysqld的服务进程,这 ...

  4. 使用7zip压解各种文件的经常使用命令

    7zip简单介绍 格式支持 压缩解压缩 仅支持解压缩 安装 Debian Ubuntu ArchLinux 使用 打包 解压 列出文件的信息列表 检查包的完整性 更新压缩包 删除包里的文件 7zip简 ...

  5. 在类的头文件里尽量少引入其它头文件 &lt;&lt;Effective Objective-C&gt;&gt;

    与C 和C++ 一样,Objective-C 也使用"头文件"(header file) 与"实现文件"(implementation file)来区隔代码.用 ...

  6. arcgis 发布地图服务

    arcgis中,地图文档需要发布,才能为WEB所用. 咋发布呢? 1.在arcmap里面,点击 文件 - 共享为 - 服务 2.在弹出的对话框里选"发布服务",然后 3.这里面有点 ...

  7. Koa2学习(五)中间件

    Koa2学习(五)中间件 Koa2通过app.use(function)方法来注册中间件. 所有的http请求都会依次调用app.use()方法,所以中间件的使用顺序非常重要. 中间件的执行顺序 官方 ...

  8. java根据文件流判断文件类型(后缀名)

    import java.io.FileInputStream; public class FileType{ public static String bytesToHexString(byte[] ...

  9. POJ3468 A Simple Problem with Integers —— 线段树 区间修改

    题目链接:https://vjudge.net/problem/POJ-3468 You have N integers, A1, A2, ... , AN. You need to deal wit ...

  10. web项目开发 之 前端规范 --- HTML编码规范

    此文严格按照W3C规范和部分实际项目可读性,浏览器加载,性能等众多属性权衡,做出平时前端编码规范文 档.供广大web工作者参考并实施,对维护和项目扩展升级都能省时省力. 转载请注明出处,JS前端实用开 ...