【windows核心编程】DLL相关(1)
DLL相关的东西
1、DLL的加载方式
隐式:
#pragma comment(lib, "XX.lib");
编译器去查找名为XX.dll的DLL,除了名字相同,该DLL和该LIB的GUID也相同。
显式:
HINSTANCE hInst = LoadLibrary(TEXT("XX.dll"));
if(NULL == hInst) retrun;
HINSTANCE hInst = LoadLibrary(TEXT("XX.dll"), NULL, FLAGS);
第三个参数为一些标志,详见核心编程。
2、DLL的入口函数
原型
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
);
其中hModule为该DLL在当前进程地址空间中的位置,ul_reason_for_call为调用此函数的原因,lpReserved如果为显式加载则为0,如果为隐式加载则为非0。
详细说一下ul_reason_for_call
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
#ifdef _DEBUG switch (ul_reason_for_call)
{
//只在该DLL第一次加载进地址空间的时候被调用一次
//此后当该DLL被加载进不同进程的地址空间时让然不调用
//当主调线程通过该reason调用DllMain函数时,主调线程不会收到DLL_THREAD_ATTACH通知
case DLL_PROCESS_ATTACH:
OutputDebugString(TEXT("\r\n***********B Dll DLL_PROCESS_ATTACH ***********\r\n"));
break; //当该DLL已经被加载到进程地址空间后,当有新【线程创建】的时候,新创建的线程先执行此段代码
//然后再去执行线程本身的代码
//不管有几个DLL,每个DLL的此处代码都会被新线程执行
case DLL_THREAD_ATTACH:
OutputDebugString(TEXT("\r\n***********B Dll DLL_THREAD_ATTACH ***********\r\n"));
break; //当该DLL已经被加载到进程地址空间后,当有【线程结束】的时候,该线程结束之前会调用此处代码
//然后才返回
//不管有几个DLL,每个DLL的此处代码都会被执行
case DLL_THREAD_DETACH:
OutputDebugString(TEXT("\r\n***********B Dll DLL_THREAD_DETACH *********** \r\n"));
break; //只有在该DLL从内存中卸载的时候才会被调用一次
case DLL_PROCESS_DETACH:
OutputDebugString(TEXT("\r\n***********B Dll DLL_PROCESS_DETACH ***********\r\n"));
break;
} #endif return TRUE;
}
demo
有两个DLL, ADll.dll 和 BDll.dll
在程序中加载这个两个DLL, 然后创建一个新线程,看输出
//加载DLL
void CUseABDllDlg::OnBnClickedBtnLoadlib()
{
HINSTANCE hInstA = LoadLibrary(_T("ADll.dll"));
HINSTANCE HIntB = LoadLibrary(_T("BDll.dll"));
if (NULL == hInstA || NULL == HIntB)
{
AfxMessageBox(_T("加载DLL失败"));
return;
}
} //线程函数
UINT WINAPI WorkThread(LPVOID lpParam)
{
#ifdef _DEBUG
OutputDebugString(TEXT("\r\n&&&&&&&&&&&&&&&&&&线程被创建&&&&&&&&&&&&&&&&&\r\n"));
#endif return 0U;
} //创建线程
void CUseABDllDlg::OnBnClickedButton2()
{
HANDLE hThread = (HANDLE)_beginthreadex(NULL, , WorkThread, NULL, , NULL);
if (NULL == hThread || INVALID_HANDLE_VALUE == hThread)
{
AfxMessageBox(_T("创建线程失败"));
}
}
输出

结论:
每创建一个新线程,当前进程地址空间中的DLL的DllMain函数都会通过DLL_THREAD_ATTACH通知被调用一次
每结束一个线程,进程地址空间空的DLL的DllMain函数都会通过DLL_THREAD_DETACH通知被调用一次。
【windows核心编程】DLL相关(1)的更多相关文章
- windows核心编程 DLL技术 【转】
注:本文章转载于网络,源地址为:http://blog.csdn.net/ithzhang/article/details/7051558 本篇文章将介绍DLL显式链接的过程和模块基地址重定位及模块绑 ...
- 《Windows核心编程系列》二十谈谈DLL高级技术
本篇文章将介绍DLL显式链接的过程和模块基地址重定位及模块绑定的技术. 第一种将DLL映射到进程地址空间的方式是直接在源代码中引用DLL中所包含的函数或是变量,DLL在程序运行后由加载程序隐式的载入, ...
- 《windows核心编程系列》十九谈谈使用远程线程来注入DLL。
windows内的各个进程有各自的地址空间.它们相互独立互不干扰保证了系统的安全性.但是windows也为调试器或是其他工具设计了一些函数,这些函数可以让一个进程对另一个进程进行操作.虽然他们是为调试 ...
- 《windows核心编程系列》十七谈谈dll
DLL全称dynamic linking library.即动态链接库.广泛应用与windows及其他系统中.因此对dll的深刻了解,对计算机软件开发专业人员来说非常重要. windows中所有API ...
- 《Windows核心编程》读书笔记 上
[C++]<Windows核心编程>读书笔记 这篇笔记是我在读<Windows核心编程>第5版时做的记录和总结(部分章节是第4版的书),没有摘抄原句,包含了很多我个人的思考和对 ...
- C++Windows核心编程读书笔记
转自:http://www.makaidong.com/%E5%8D%9A%E5%AE%A2%E5%9B%AD%E6%96%87/71405.shtml "C++Windows核心编程读书笔 ...
- 【转】《windows核心编程》读书笔记
这篇笔记是我在读<Windows核心编程>第5版时做的记录和总结(部分章节是第4版的书),没有摘抄原句,包含了很多我个人的思考和对实现的推断,因此不少条款和Windows实际机制可能有出入 ...
- 《windows核心编程系列》二十一谈谈基址重定位和模块绑定
每个DLL和可执行文件都有一个首选基地址.它表示该模块被映射到进程地址空间时最佳的内存地址.在构建可执行文件时,默认情况下链接器会将它的首选基地址设为0x400000.对于DLL来说,链接器会将它的首 ...
- 《windows核心编程系列》十六谈谈内存映射文件
内存映射文件允许开发人员预订一块地址空间并为该区域调拨物理存储器,与虚拟内存不同的是,内存映射文件的物理存储器来自磁盘中的文件,而非系统的页交换文件.将文件映射到内存中后,我们就可以在内存中操作他们了 ...
- windows核心编程 - 线程同步机制
线程同步机制 常用的线程同步机制有很多种,主要分为用户模式和内核对象两类:其中 用户模式包括:原子操作.关键代码段 内核对象包括:时间内核对象(Event).等待定时器内核对象(WaitableTim ...
随机推荐
- 李洪强iOS开发之让您的Xcode键字如飞
手指在键盘上飞速跳跃,终端上的代码也随着飞舞,是的这确实很酷.优秀的程序员总是这么一群人,他们不拘于现状,不固步自封,他们喜欢新奇的事,他们把自己发挥到极致. 指法攻略 放下您钟爱的鼠标吧,在前行之中 ...
- *[topcoder]LCMSetEasy
http://community.topcoder.com/stat?c=problem_statement&pm=13040 DFS集合全排列+LCM和GCD.但事实上,有更简单的算法,列在 ...
- SpringMVC学习总结(二)——DispatcherServlet详解
摘要: DispatcherServlet是前端控制器设计模式的实现,提供Spring Web MVC的集中访问点,而且负责职责的分派,而且与Spring IoC容器无缝集成,从而可以获得Spring ...
- 什么叫非阻塞io
而一个NIO的实现会有所不同,下面是一个简单的例子: ByteBuffer buffer = ByteBuffer.allocate(48); int bytesRead = inChannel.re ...
- Java学习笔记之:Java数据类型的转换
一.介绍 数据类型的转换,分为自动转换和强制转换.自动转换是程序在执行过程中“悄然”进行的转换,不需要用户提前声明,一般是从位数低的类型向位数高的类型转换:强制类型转换则必须在代码中声明,转换顺序不受 ...
- 解决Nginx下WordPress后台404的问题
在把这个博客做好后,上传到nginx服务器上却出现问题. 首先是wordpress官方的伪静态是通过.htaccess实现的,但nginx并不支持.htaccess,无奈只好在网上找到wordpres ...
- 最受欢迎的5款PHP框架记录,我居然一个不知道。。。
1. CodeIgniter Framework CodeIgniter 是目前使用最广泛的 PHP 框架.CodeIgniter 是一个简单快速的PHP MVC 框架.EllisLab 的工作人员发 ...
- Java解压上传zip或rar文件,并解压遍历文件中的html的路径
1.本文只提供了一个功能的代码 public String addFreeMarker() throws Exception { HttpSession session = request.getSe ...
- Uboot 2014.07 makefile分析 - 其他Cortex系列
uboot的官网可以通过谷歌搜索得到,显示结果第一个链接就是. 官网:: http://www.denx.de/wiki/U-Boot ftp下载: ftp://ftp.denx.de/pub/u-b ...
- BZOJ3122 随机数生成器
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=3122 题意: 思路:(1)x1=t则n=1; (2)a=0,则b=t,n=2;否则无解: ...