用内存查看工具vmmap来理解HINSTANCE和HMODULE的具体含义
做win32开发以来,HINSTANCE和HMODULE用到的地方很多,一般而言,HINSTANCE指的是跟exe相关的,HMODULE跟dll相关。
比如win32界面程序,
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,_In_opt_ HINSTANCE hPrevInstance,_In_ LPWSTR lpCmdLine,_In_ int nCmdShow)
{UNREFERENCED_PARAMETER(hPrevInstance);UNREFERENCED_PARAMETER(lpCmdLine);// TODO: Place code here.// Initialize global stringsLoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);LoadStringW(hInstance, IDC_SIMPLEMESSAGE, szWindowClass, MAX_LOADSTRING);MyRegisterClass(hInstance);...
}
此段代码中,wWinMain函数的第一个参数就是HINSTANCE,代表当前进程exe的实例句柄。
而关于HMODULE的,最常见的是下面的dll动态加载,返回的是dll的实例句柄。
HMODULE WINAPI LoadLibrary(_In_ LPCTSTR lpFileName
);
无论是exe,还是dll,上面讲的实例句柄都比较抽象,能否以感官认知,来进行理解,为此我此处用到了内存查看工具VMMap。
首先,我们来用win32窗口例子来说明,此处我用的是vs2015,固定住exe在虚拟内存中的加载地址,如下所示:
红色笔圈住的地方,就是exe在进程中的映射地址,此处填写的是0x00df0000,关于如何固定住exe基址,大家可以网上搜索。然后运行此exe,出现的是一个窗体界面。我们用vmmap来查看此进程的虚拟地址空间。
我们直接找0x00df0000打头的地址,可以看到,对应的模块就是exe本身。
并且还可以看出,此exe本身占用了多大的虚拟内存空间,在展开的若干行中,列举了此exe内部的若干区段,比如Header段,指的就是头部信息所在的段,占用了4K的大小空间,.text段是代码段,也占用了4K的大小空间,最后一个.rsrc,资源区段,占用了96K的空间,可以看出,对于界面程序而言,一般资源占用的空间最大。
通过上面的例子,可以看出,HINSTANCE其实就是模块exe加载到进程虚拟地址空间后的映射地址。
那么HMODULE对应的dll,是不是也是一样的呢,我们编写一个例子看看。
此处编写一个求两个正整数的最大公约数的例子,dll中导出函数,如下所示:
extern “C” __declspec(dllexport) int _stdcall Gcd(int a, int b);
Gcd就表示求a和b的最大公约数。对应的dll的名称叫做GcdDll.dll。
然后写一个exe(GcdExe.exe),动态加载此dll,代码如下:
#include "stdafx.h"
#include <stdio.h>
#include <Windows.h>typedef int (CALLBACK *GCD)(int, int);int main()
{int a = 150;int b = 200;HMODULE hModule = LoadLibraryA("GcdDll.dll");printf("hModule is %p\n", hModule);GCD gcd = (GCD)GetProcAddress(hModule, "Gcd");printf("address of Gcd is %p\n", gcd);int c = gcd(a, b);printf("the common division of %d and %d is %d\n", a, b, c);while (1);return 0;
}
运行结果如下所示:
可以看出,dll加载到进程虚拟地址空间的地址是0x66B50000,而导出函数Gcd在进程虚拟地址空间的地址是0x66B51010。
下面我们来用内存查看工具查看进程GcdExe.exe的地址空间
可以看出,此dll映射到进程的地址空间的地址就是0x66B50000,而Gcd的地址0x66B51010是怎么来的呢,我们可以借助depends工具,查看GcdDll.dll,如下所示:
我们查看右边的导出函数Gcd所在的条目,里面有个Entry Point,值是0x00001010,此值是此函数相对于此dll的偏移地址。
所以Gcd函数在进程地址空间的地址0x66B51010,就是Gcd函数所在模块GcdDll.dll的映射地址0x66B50000加上Gcd函数在dll内的偏移地址0x00001010。
顺带说下,exe和dll在我看来没什么不同,LoadLibrary也可以加载exe。
关于内存查看工具vmmap.exe,本来想上传资源的,结果发现已经有人上传,我上传不了,大家自己找吧。
用内存查看工具vmmap来理解HINSTANCE和HMODULE的具体含义相关推荐
- android--MAT、DDMS 等内存查看工具
android之 MAT.DDMS 等内存查看工具 最近学习内存管控 看到一些很好的文章 整合一下: Android开发Eclipse中DDMS中Heap使用及GC_EXTERNAL_ALLOC含义 ...
- java 查看内存_java 内存查看工具
业界有很多强大的java profile的工具,比如Jporfiler,yourkit,这些收费的东西我就不想说了,想说的是,其实java自己就提供了很多内存监控的小工具,下面列举的工具只是一小部分, ...
- android之 MAT、DDMS 等内存查看工具
最近学习内存管控 看到一些很好的文章 整合一下: Android开发Eclipse中DDMS中Heap使用及GC_EXTERNAL_ALLOC含义 http://blog.csdn.net/ding ...
- linux电脑内存查看工具,Linux内存查看工具---Smem
物理内存不足对Linux桌面系统和服务器系统的性能影响都很大.当你的计算机变慢时,要做的第一件事就是释放内存.尤其是在多用户环境以及执行关键任务的服务器环境下,内存消耗会变得更加关键,因为多个用户和应 ...
- 内存查看工具RAMMAP说明
参考 Technet Process Private: 分配给单一Process专用的内存 Mapped File: 用来储放档案内容快取(Cache)的内存空间 Shared Mem ...
- jvm 内存查看与分析工具
转自http://jameswxx.iteye.com/blog/731763 业界有很多强大的java profile的工具,比如Jporfiler,yourkit,这些收费的东西我就不想说了,想说 ...
- java内存分析工具_java内存查看与分析
业界有很多强大的java profile的工具,比如Jporfiler,yourkit,这些收费的东西我就不想说了,想说的是,其实java自己就提供了很多内存监控的小工具,下面列举的工具只是一小部分, ...
- 虚拟机常用的内存查看与分析工具
内存查看与分析工具,下面是日常监控可以使用的一些工具, 在调试时应用比较多的是堆栈信息,查看这篇文章: Java Thread Dump 性能分析 gc日志输出 在jvm启动参数中加入 1 2 3 4 ...
- 初步了解Windows应用程序内存结构 - 使用VMMAP工具
VMMap工具在此下载: https://docs.microsoft.com/zh-cn/sysinternals/downloads/vmmap VMMap 是一个进程虚拟和物理内存分析实用程序. ...
最新文章
- centos php svn,centos7中搭建svn服务器(示例代码)
- P3605 [USACO17JAN]Promotion Counting晋升者计数
- python csv字符串写入_请教:如何把csv里的 emoji 字符串正确写入 DB?
- SpringBoot中访问静态资源
- delphi和 java通过socket通信的中文问题
- POJ 3694 Network ★(边双连通分量+并查集缩点+LCA)
- 201609计算机控制技术作业三,计算机控制技术大作业2015..doc
- ring0 ring3 kernel driver
- hdu 1466 计算直线的交点数 递推
- Oracle中的Round和Trunc
- 7 天 600 stars, Mobi.css 是如何诞生的
- 老肖有话说:如期而至的Swarm新工具Crane开源解读
- linux引导界面含义,Linux引导时输入特殊信息的含义的方法
- 孙玄:构建企业级业务高可用的延时消息中台
- 基于51单片机超声波红外避障语音导盲仪设计(全套资料)
- OPNsense用户手册-用户管理
- 什么是计算机科学中的“本体论”
- (对对碰)软工结对作业
- 全屏的微粒子3D动画特效
- 尚好房 07_前端房源展示