关闭

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

171人阅读 评论(0) 收藏 举报
分类:

前言

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;
	;
}


风行者引领群雄者行风

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:32119次
    • 积分:1297
    • 等级:
    • 排名:千里之外
    • 原创:101篇
    • 转载:8篇
    • 译文:0篇
    • 评论:2条
    最新评论