动态链接库 隐式链接 首次接触分歧定义(同样字段cpp中翻译为export 头文件里翻译为import)

原创 2015年07月08日 17:25:05

前言

WIN API的所有函数都包含在DLL中,最重要的有三个DLL

Kernel32.dll管理内存 进程 和线程

User32.dll 窗口界面与消息

GDI32.dll 画图和显示文本


加载DLL的方式有两种 隐式链接 显示加载

两种方法对于你的程序调用动态库时没有任何区别,只是你在编程时,步骤是不一样的。显式调用麻烦了点,但可以没有相应的lib库;隐式调用,使用起来比较简单,有函数的声明就可以了,但必须有lib库。
隐式加载默认是加载到内存中的,始终占用内存。显示加载,你加载时占用内存,释放了就不占用内存了。如果该DLL已经载入,loadlibrary只是会增加一个引用计数,相同,freelibrary也只是减少引用计数,如果引用计数为0时,DLL才从内存中移除。

隐式链接的缺点:使用比较简单,在程序的其他部分可以任意使用函数,但是当程序访问十来个dll动态链接库的时候,此时如果都使用隐式链接的时候,启动此程序的时候,这十来个动态链接库都需要加载到内存,映射到内存的地址空间,这就会加大进程的启动时间


隐式链接

隐式的加载时链接的方法如下

DLL工程编译后 会产生两个文件 一个是DLL 一个是LIB

将LIB文件复制到testB文件夹里(textB与Debug和Release文件夹平级)

将DLL文件复制到Debug文件夹里(不复制编译能通过但不能运行)

==============================================================================

DLL工程为win32 dll 空文件工程

添加 cpp文件 jisuan.cpp

_declspec(dllexport) int add(int a,int b)
{
	return a+b;
}
编译 产生DLL  和LIB
==============================================================================

测试端工程 为MFC对话框工程

在stdafx.h中

#pragma comment (lib,"0708A.lib")
在Dlg.cpp中

extern int add(int, int);
void CtestBDlg::OnBnClickedButton1()
{
	// TODO: Add your control notification handler code here
	this->m_z=add(3,4);<span style="white-space:pre">	</span>//m_z是静态文本框成员 用来显示计算结果
	this->UpdateData(0);
}
将LIB文件复制到testB文件夹里(textB与Debug和Release文件夹平级)

编译但不运行,生成Debug文件夹

将DLL文件复制到Debug文件夹里

运行,OK


为隐式链接提供头文件

至此 在应用端每使用一个函数都需要做一个声明

这样对DLL使用者不方便 

可以提供给使用者一个  .h文件  使用者#include 这个.h 文件后 就不再需要对每个函数作声明了


为DLL工程添加.h 文件   jisuan.h

//  这个.h文件 是给应用端使用的 所以是import而不是export
_declspec(dllimport) int add(int,int);
_declspec(dllimport) int substract(int,int);
_declspec(dllimport) int multi(int,int);
_declspec(dllimport) int divide(int,int);

将这个头文件也复制到 lib 所在的文件夹下

为测试工程添加

#pragma comment (lib,"0709A.lib")
#include "jisuan.h"<span style="white-space:pre">	</span>//新加的
然后就可以把测试工程里的函数声明都删掉了


现在只需要更换dll文件 就能使exe的功能改变 (偷偷将DLL的减法改为加法,然后替换DEBUG文件夹下原有的DLL)


分歧翻译使.h文件既能被应用端外部引用

也能被.cpp文件引用(其实没啥用)

改造前的 .h 和.cpp文件

.h

//  这个.h文件 是给应用端使用的 所以是import而不是export
_declspec(dllimport) int add(int,int);
_declspec(dllimport) int substract(int,int);
_declspec(dllimport) int multi(int,int);
_declspec(dllimport) int divide(int,int);
.cpp

_declspec(dllexport) int add(int a,int b)
{
	return a+b;
}

_declspec(dllexport) int substract(int a,int b)
{
	return a-b;
}

_declspec(dllexport) int multi(int a,int b)
{
	return a*b;
}

_declspec(dllexport) int divide(int a,int b)
{
	if(b==0)
	{
		return 12345;
	}
	return a/b;
	;

改造中的cpp

_declspec(dllexport) int add(int,int);
_declspec(dllexport) int substract(int,int);
_declspec(dllexport) int multi(int,int);
_declspec(dllexport) int divide(int,int);

int add(int a,int b)
{
	return a+b;
}

int substract(int a,int b)
{
	return a-b;
}

int multi(int a,int b)
{
	return a*b;
}

int divide(int a,int b)
{
	if(b==0)
	{
		return 12345;
	}
	return a/b;
	;
}
改造后的 .h 和.cpp文件
.h

//改造后 这个.h文件既可以给应用端用 也可以帮本地的cpp文件作下声明(其实没啥用)
#ifndef __JISUAN_0709A__
#define __JISUAN_0709A__ _declspec(dllimport)
#endif

__JISUAN_0709A__ int add(int,int);
__JISUAN_0709A__ int substract(int,int);
__JISUAN_0709A__ int multi(int,int);
__JISUAN_0709A__ int divide(int,int);

.cpp

#define __JISUAN_0709A__ _declspec(dllexport)
#include "jisuan.h"	//因为有上一句,头文件里的JISUAN将被翻译成export而不是import

int add(int a,int b)
{
	return a+b;
}

int substract(int a,int b)
{
	return a-b;
}

int multi(int a,int b)
{
	return a*b;
}

int divide(int a,int b)
{
	if(b==0)
	{
		return 12345;
	}
	return a/b;
	;
}


风行者引领群雄者行风

相关文章推荐

程序编译、链接、运行时头文件或动态链接库的查找

本文转自:http://blog.csdn.net/dlutxie/article/details/6776936           当考虑怎样总结这个头文件及动态链接库的查找问题时,我想到了一个...

隐式的调用动态链接库

  • 2011年07月06日 08:46
  • 5.79MB
  • 下载

动态链接库的隐式调用

  • 2010年07月02日 09:22
  • 70KB
  • 下载

Linux 动态链接库与静态链接库---隐式链接

动态链接库也被称为共享对象shared object,默认扩展名为so,动态链接库的优点如下: (1) 动态的加载,就是当这个运行的模块在需要的时候才被映射入运行模块的虚拟内存空间中, 如一个模块...

opengl的动态链接库和头文件

  • 2010年01月28日 16:04
  • 253KB
  • 下载

opengl 动态链接库及头文件

  • 2008年12月13日 10:54
  • 1.05MB
  • 下载

gcc指定头文件及动态链接库路径

在利用源代码进行软件编译的过程中,经常会出现以下错误: undefined reference to ‘crypt’ libdl.so: error adding symbols: DSO missi...

gcc指定头文件路径及动态链接库路径

gcc指定头文件路径及动态链接库路径   本文详细介绍了linux 下gcc头文件指定方法,以及搜索路径顺序的问题。另外,还总结了,gcc动态链接的方法以及路径指定,同样也讨论了搜索路径的...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:动态链接库 隐式链接 首次接触分歧定义(同样字段cpp中翻译为export 头文件里翻译为import)
举报原因:
原因补充:

(最多只允许输入30个字)