动态链接库 隐式链接 首次接触分歧定义(同样字段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;
	;
}


风行者引领群雄者行风

机器学习中的噪音(机器学习基石)

noise的产生在机器学习中我们在独立随机抽样的时候会出现一些搞错的信息,这些错误的数据我们称之为杂讯(或者噪音  noise),一般可以归结为一下两种(以二分为例):输出错误:1.同样的一笔数据会出...
  • qq_34993631
  • qq_34993631
  • 2018年02月01日 23:59
  • 38

JS----数子翻译英文

数子翻译英文
  • damys
  • damys
  • 2012年12月05日 09:54
  • 714

【读书笔记】iOS-使用Web Service-基于客户端服务器结构的网络通信(一)

Web Service技术是一种通过Web协议提供服务,保证不同平台的应用服务可以互操作,为客户端程序提供不同的服务。 目前3种主流的Web Service实现方案用:REST,SOAP和XML...
  • fanqingtulv
  • fanqingtulv
  • 2015年11月23日 09:35
  • 323

公式翻译

 又是一个寒冷的夜晚,我坐在床头,这个时候我只有两件事情能做,一是看《圣经》,一是看《数据结构》,但明显前者对我来说比后者难得多,一来我不是信徒,二来内容是在枯燥,缺乏创造性,但更关键的是:其实我没有...
  • guogangj
  • guogangj
  • 2006年12月20日 00:19
  • 2590

REST----表述性状态转移

REST相关知识的链接
  • u013919153
  • u013919153
  • 2017年06月05日 15:57
  • 370

拼音翻译为阿拉伯数字

#include #include #include #include using namespace std; int main() { string name[]={"Shi","B...
  • zlin532
  • zlin532
  • 2014年08月08日 11:12
  • 182

Unity3D: JavaScript->C# 或 C#->JavaScript的调用

在进行Unity3D 编程时,有些情况下,我们需要访问另一个不是我们正在使用的编程语言的脚本。虽然强烈推荐将所有脚本转换成一种,但是知道如何从一个JavaScript类访问一个C#脚本及反过来的情况是...
  • wlj613613
  • wlj613613
  • 2014年02月24日 17:11
  • 1970

linux 串口 c语言编程需要注意的事项

tcflush() 丢弃要写入引用的对象,但是尚未传输的数据,或者收到但是尚未读取的数据,取决于 queue_selector 的值:   TCIFLUSH   刷新收到的数据但是不读 ...
  • lqxandroid2012
  • lqxandroid2012
  • 2017年12月11日 22:45
  • 46

c++中将数字转化为字符串

string main_pro::double_to_str(double a) { char buffer[30]; string str1; sprintf_s(b...
  • u013230291
  • u013230291
  • 2017年03月03日 16:20
  • 126

文本转换为HTML文字编码

 /** * 转换为HTML文字编码. */ public static String htmlTextEncoder(String src) throws Exception {   if (src...
  • yehell
  • yehell
  • 2007年08月23日 22:06
  • 691
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:动态链接库 隐式链接 首次接触分歧定义(同样字段cpp中翻译为export 头文件里翻译为import)
举报原因:
原因补充:

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