您的位置:首页 > 编程语言

VS2015动态库编程之入口函数

2017-07-10 06:51 253 查看
本文章相关视频教程下载地址http://pan.baidu.com/s/1slK2Hat

对于可执行文件,其入口函数为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。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: