动态链接库 隐式链接 首次接触分歧定义(同样字段cpp中翻译为export 头文件里翻译为import)
2015-07-08 17:25
127 查看
前言
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
==============================================================================
测试端工程 为MFC对话框工程
在stdafx.h中
编译但不运行,生成Debug文件夹
将DLL文件复制到Debug文件夹里
运行,OK
为隐式链接提供头文件
至此 在应用端每使用一个函数都需要做一个声明
这样对DLL使用者不方便
可以提供给使用者一个 .h文件 使用者#include 这个.h 文件后 就不再需要对每个函数作声明了
为DLL工程添加.h 文件 jisuan.h
将这个头文件也复制到 lib 所在的文件夹下
为测试工程添加
现在只需要更换dll文件 就能使exe的功能改变 (偷偷将DLL的减法改为加法,然后替换DEBUG文件夹下原有的DLL)
分歧翻译使.h文件既能被应用端外部引用
也能被.cpp文件引用(其实没啥用)
改造前的 .h 和.cpp文件
.h
改造中的cpp
.h
.cpp
风行者引领群雄者行风
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; ; }
风行者引领群雄者行风
相关文章推荐
- c++ web服务器
- C/C++程序员简历模板
- C语言 system()函数打开一个程序,路径有空格的问题
- c++空类实例大小不是0原因
- 学堂在线C++进阶 编程题 10-2
- GetMemory错误讲解(指针练习)----C++面试之GetMemory问题
- C++ STL queue队列
- C++ STL stack栈
- C++容器-STL
- C++ STL deque可变数组
- 关于struct的细节
- 找不到min和max标识符—C++中头文件次序问题
- 【Visual C++】游戏开发笔记三十七 浅墨DirectX提高班之五 顶点缓存的红颜知己:索引缓存的故事
- 【Visual C++】游戏开发笔记三十六 浅墨DirectX提高班之四 顶点缓存的逆袭
- MFC生成。exe文件名更改方法
- C++的XML编程经验――LIBXML2库使用指南
- 怎样管理C++类中的指针成员 和 简单的c++智能指针使用的例子
- C++ Primer学习笔记(13)——封装、继承、多态
- C++学习笔记 extern C
- 【c语言】输入一组整数,求出最大子序列的和