动态链接库(DLL) 分类: c/c++ 2015-01-04 23:30 423人阅读 评论(0) 收藏
动态链接库:我们经常把常用的代码制作成一个可执行模块供其他可执行文件调用,这样的模块称为链接库,分为动态链接库和静态链接库。
对于静态链接库,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) 收藏的更多相关文章
- 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 ...
- android开发之调试技巧 分类: android 学习笔记 2015-07-18 21:30 140人阅读 评论(0) 收藏
我们都知道,android的调试打了断点之后运行时要使用debug as->android application 但是这样的运行效率非常低,那么我们有没有快速的方法呢? 当然有. 我们打完断点 ...
- HDU 1272 小希的迷宫(并查集) 分类: 并查集 2015-07-07 23:38 2人阅读 评论(0) 收藏
Description 上次Gardon的迷宫城堡小希玩了很久(见Problem B),现在她也想设计一个迷宫让Gardon来走.但是她设计迷宫的思路不一样,首先她认为所有的通道都应该是双向连通的,就 ...
- MS SQL数据批量备份还原(适用于MS SQL 2005+) 分类: SQL Server 数据库 2015-03-10 14:32 103人阅读 评论(0) 收藏
我们知道通过Sql代理,可以实现数据库的定时备份功能:当数据库里的数据库很多时,备份一个数据库需要建立对应的定时作业,相对来说比较麻烦: 还好,微软自带的osql工具,比较实用,通过在命令行里里输入命 ...
- 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 ...
- ubuntu14.04使用root用户登录桌面 分类: 学习笔记 linux ubuntu 2015-07-05 10:30 199人阅读 评论(0) 收藏
ubuntu安装好之后,默认是不能用root用户登录桌面的,只能使用普通用户或者访客登录.怎样开启root用户登录桌面呢? 先用普通用户登录,然后切换到root用户,然后执行如下命令: vi /usr ...
- Matlab调用C程序 分类: Matlab c/c++ 2015-01-06 19:18 464人阅读 评论(0) 收藏
Matlab是矩阵语言,如果运算可以用矩阵实现,其运算速度非常快.但若运算中涉及到大量循环,Matlab的速度令人难以忍受的.当必须使用for循环且找不到对应的矩阵运算来等效时,可以将耗时长的函数用C ...
- Mahout快速入门教程 分类: B10_计算机基础 2015-03-07 16:20 508人阅读 评论(0) 收藏
Mahout 是一个很强大的数据挖掘工具,是一个分布式机器学习算法的集合,包括:被称为Taste的分布式协同过滤的实现.分类.聚类等.Mahout最大的优点就是基于hadoop实现,把很多以前运行于单 ...
- 各种排序算法的分析及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 ...
随机推荐
- CentOS 5 全功能服务器搭建
转自: http://www.php-oa.com/2007/12/27/centos-www.html 转:主要做为历史记录,以后用.另外很少见这么好的编译的文章,其实我不推荐用编译安装.但这个文章 ...
- sqoop基本 操作
列出 hive的 全部库 sqoop list-databases --connect jdbc:mysql://localhost --username hive --password hive 列 ...
- Failed to load resource: the server responded with a status of 404 (Not Found)
Failed to load resource: the server responded with a status of 404 (Not Found) 报错情况:图标加载失败 原因分析:路径错误 ...
- react 开发 PC 端项目(一)项目环境搭建 及 处理 IE8 兼容问题
步骤一:项目环境搭建 首先,你不应该使用 React v15 或更高版本.使用仍然支持 IE8 的 React v0.14 即可. 技术选型: 1.react@0.14 2.bootstrap3 3. ...
- 利用wxpython编写GUI
首先建立一个简单的布局合理的图形界面,但是其中按下按键没有事情发生 #encoding=utf-8 __author__ = 'heng' #编写一个GUI import wx app = wx.Ap ...
- Visual Studio 2017中使用正则修改部分内容 如何使用ILAsm与ILDasm修改.Net exe(dll)文件 C#学习-图解教程(1):格式化数字字符串 小程序开发之图片转Base64(C#、.Net) jquery遍历table为每一个单元格取值及赋值 。net加密解密相关方法 .net关于坐标之间一些简单操作
Visual Studio 2017中使用正则修改部分内容 最近在项目中想实现一个小工具,需要根据类的属性<summary>的内容加上相应的[Description]特性,需要实现的效 ...
- BC1.2的一些心得
什么叫DCD DataContact Detect(DCD) 1.首先是DCD 2.然后是Primary detection 3.然后是Secondary detection 检測充电的条件是VBUS ...
- Spring如何实现IOC和AOP的,说出实现原理。
用过spring的朋友都知道spring的强大和高深,都觉得深不可测,其实当你真正花些时间读一读源码就知道它的一些技术实现其实是建立在一些最基本的技术之上而已:例如AOP(面向方面编程)的实现是建立在 ...
- POJ3468 A Simple Problem with Integers —— 线段树 区间修改
题目链接:https://vjudge.net/problem/POJ-3468 You have N integers, A1, A2, ... , AN. You need to deal wit ...
- HTTP协议 (一) HTTP协议详解
当今web程序的开发技术真是百家争鸣,ASP.NET, PHP, JSP,Perl, AJAX 等等. 无论Web技术在未来如何发展,理解Web程序之间通信的基本协议相当重要, 因为它让我们理解了We ...