VS2015动态库编程之入口函数

本文章相关视频教程下载地址http://pan.baidu.com/s/1slK2Hat

对于可执行文件,其入口函数为WinMain(),对于动态库文件,其入口函数为DllMain()。当系统加载动态库文件时,就会调用该文件的DllMain()函数。

1 DllMain()函数的格式

VS2015中创建一个Win32动态库项目,项目名为“DLL_Variant_Test”。此时,在“解决方案资源管理器”的“源文件”中包含了3个源文件:DLL_Variant_Test.cppdllmain.cppstdafx.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


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值