VS2015动态库编程之入口函数
2017-07-10 06:51
253 查看
本文章相关视频教程下载地址http://pan.baidu.com/s/1slK2Hat
对于可执行文件,其入口函数为WinMain(),对于动态库文件,其入口函数为DllMain()。当系统加载动态库文件时,就会调用该文件的DllMain()函数。
dllmain()函数的格式为
BOOL APIENTRY DllMain(
HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
其中,APIENTRY的定义为
#define APIENTRY WINAPI
表示DllMain()是Windows API函数。第一个参数hModule表示动态库模块的句柄,当动态库第一次被加载时,它的句柄会通过此参数传递到dllMain()函数中;ul_reason_for_call表示调用该动态库入口函数的原因;lpReserved是保留参数。
#include <iostream>
之后将dllMain()函数修改为如下形式
BOOL APIENTRY DllMain(
HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
std::cout << "DLL_PROCESS_ATTACH.\n";
break;
case DLL_THREAD_ATTACH:
std::cout << "DLL_THREAD_ATTACH.\n";
break;
case DLL_THREAD_DETACH:
std::cout << "DLL_THREAD_DETACH.\n";
break;
case DLL_PROCESS_DETACH:
std::cout << "DLL_PROCESS_DETACH.\n";
break;
}
return TRUE;
}
对于调用动态库的不同原因,会输出不同的信息。
#include "stdafx.h"
#include <Windows.h>
#include <iostream>
using namespace std;
DWORD WINAPI MyThread(LPVOID lpParameter)
{
return 0;
}
int main()
{
HINSTANCE hinstLib;
HANDLE myThread_Handle;
hinstLib = LoadLibrary(_T("DLL_Variant_Test.dll"));
myThread_Handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MyThread,
NULL, 0,
NULL);
WaitForSingleObject(myThread_Handle, INFINITE);
FreeLibrary(hinstLib);
return 0;
}
程序运行效果如图1所示。
图1
程序运行效果
当调用LoadLibrary()函数时,动态库的dllMain()函数被调用,此时ul_reason_for_call的值是DLL_PROCESS_ATTACH;当调用CreateThread()函数创建线程时,ul_reason_for_call的值是DLL_THREAD_ATTACH;使用WaitForSingleObject()函数等待创建的线程结束时,ul_reason_for_call的值是DLL_THREAD_DETACH;最后调用FreeLibrary()函数释放动态库时,ul_reason_for_call的值是DLL_PROCESS_DETACH。
对于可执行文件,其入口函数为WinMain(),对于动态库文件,其入口函数为DllMain()。当系统加载动态库文件时,就会调用该文件的DllMain()函数。
1 DllMain()函数的格式
在VS2015中创建一个Win32动态库项目,项目名为“DLL_Variant_Test”。此时,在“解决方案资源管理器”的“源文件”中包含了3个源文件:DLL_Variant_Test.cpp、dllmain.cpp和stdafx.cpp。可以在DLL_Variant_Test.cpp中定义动态库的导出函数,而动态库的入口函数在dllmain.cpp中。dllmain()函数的格式为
BOOL APIENTRY DllMain(
HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
其中,APIENTRY的定义为
#define APIENTRY WINAPI
表示DllMain()是Windows API函数。第一个参数hModule表示动态库模块的句柄,当动态库第一次被加载时,它的句柄会通过此参数传递到dllMain()函数中;ul_reason_for_call表示调用该动态库入口函数的原因;lpReserved是保留参数。
2 DllMain()函数的默认定义
在DllMain()函数的默认定义中,通过switch/case语句对其第二个参数ul_reason_for_call进行判断,该参数的取值及含义如表1所示。取值 | 含义 |
DLL_PROCESS_ATTACH | 进程第一次加载动态库并调用DllMain函数 |
DLL_PROCESS_DETACH | 进程结束 |
DLL_THREAD_ATTACH | 当前进程正创建一个新线程 |
DLL_THREAD_DETACH | 线程结束 |
3 DllMain()函数的调用时机
通过输出信息来验证DllMain()函数的调用时机。3.1 在入口函数中添加输出信息
在DLL_Variant_Test项目的dllmain.cpp中添加头文件#include <iostream>
之后将dllMain()函数修改为如下形式
BOOL APIENTRY DllMain(
HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
std::cout << "DLL_PROCESS_ATTACH.\n";
break;
case DLL_THREAD_ATTACH:
std::cout << "DLL_THREAD_ATTACH.\n";
break;
case DLL_THREAD_DETACH:
std::cout << "DLL_THREAD_DETACH.\n";
break;
case DLL_PROCESS_DETACH:
std::cout << "DLL_PROCESS_DETACH.\n";
break;
}
return TRUE;
}
对于调用动态库的不同原因,会输出不同的信息。
3.2 创建用来调用动态库的程序
创建一个Win32控制台程序,在该控制台程序中,使用LoadLibrary()函数动态加载在“3.1”中生成的动态库,再加载完动态库后,通过CreateThread()函数创建一个线程,等待线程结束后,再使用FreeLibrary()函数释放该动态库。代码如下所示#include "stdafx.h"
#include <Windows.h>
#include <iostream>
using namespace std;
DWORD WINAPI MyThread(LPVOID lpParameter)
{
return 0;
}
int main()
{
HINSTANCE hinstLib;
HANDLE myThread_Handle;
hinstLib = LoadLibrary(_T("DLL_Variant_Test.dll"));
myThread_Handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MyThread,
NULL, 0,
NULL);
WaitForSingleObject(myThread_Handle, INFINITE);
FreeLibrary(hinstLib);
return 0;
}
程序运行效果如图1所示。
图1
程序运行效果
当调用LoadLibrary()函数时,动态库的dllMain()函数被调用,此时ul_reason_for_call的值是DLL_PROCESS_ATTACH;当调用CreateThread()函数创建线程时,ul_reason_for_call的值是DLL_THREAD_ATTACH;使用WaitForSingleObject()函数等待创建的线程结束时,ul_reason_for_call的值是DLL_THREAD_DETACH;最后调用FreeLibrary()函数释放动态库时,ul_reason_for_call的值是DLL_PROCESS_DETACH。
相关文章推荐
- VS2015动态库编程之Win32动态库的使用(中)
- VS2015用C++创建的动态库导出函数名乱码原因分析
- VS2015动态库编程之导出C++类(下)
- VS2015动态库编程之Win32动态库的使用(上)
- VS2015动态库编程之Win32动态库的使用(下)
- VS2015动态库编程之MFC规则动态库(下)
- VS2015动态库编程之MFC规则动态库(中)
- VS2015动态库编程之MFC扩展动态库(上)
- 【Fltk】Fltk1.3.3+VS2015 编程
- 在VS2015中用C++编写可被其它语言调用的动态库DLL
- 【逆向工具】IDA使用2-VS2015版本release查找main函数入口,局部变量
- 在VS2015中用C++创建MFC规则动态库DLL
- VS2015自定义编程背景
- linux动态库的入口和出口函数
- c++中strcpy函数在VS2015无法使用的问题
- VS2013/MFC编程入门之八(对话框:为控件添加消息处理函数)
- VS2015编译32位Opencv310(动态库+静态库,文末有下载链接)
- 在VS2015中用C++创建动态库并用C#调用
- Windows编程 VC++6.0到VS2015 实例小游戏的简单移植 VS下常见错误的排查
- 关于vs2015不能使用inet_addr等函数