源码路径:dangwei-90/DllLoadAndFree (github.com)
DLL隐式调用的加载和卸载顺序:[DLL] dll 的加载和卸载顺序 (隐式调用)_二七-CSDN博客
dll 分为显示加载和隐式加载。
假设 program 加载 dllA , 而dllA 加载 dllB, 显示加载顺序如下:
1. program 启动
2. dllA 被加载
3. dllB 被加载
这是因为 dllB 是被 dllA 动态加载的,所以 dllA 一定先被 program 加载。
同理,显示卸载顺序如下:
1. dllB 被卸载
2. dllA 被卸载
3. program 退出
因为 dllA 动态加载的 dllB,所以 dllA 卸载前,会先卸载由它加载的 dllB。
demo 如下:
// program : CallDllProject
// 用于加载 dllA
#include <iostream>
#pragma comment(lib,"DllA.lib")
extern "C" _declspec(dllimport) int addtest(int a, int b);
int main()
{
int num = addtest(1, 2);
std::cout << num << std::endl;
return 0;
}
#include "pch.h"
/// 隐式调用 ///
//#pragma comment(lib,"DllB.lib")
//extern "C" _declspec(dllimport) int subtest(int a, int b);
/// 隐式调用 ///
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
MessageBoxA(NULL, "DLL A attach.", "DLL A", MB_OK);
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
MessageBoxA(NULL, "DLL A detach.", "DLL A", MB_OK);
break;
}
return TRUE;
}
// DLLA 的方法的实现
#include "stdio.h"
#include "pch.h"
extern "C" _declspec(dllexport) int addtest(int a, int b) {
// 隐式调用
// subtest(5,1);
// 显示调用
typedef int(*psubtest)(int a, int b);
psubtest subtest;
HINSTANCE hDLL = LoadLibrary(L"DllB.dll");
subtest = (psubtest)GetProcAddress(hDLL, "subtest");
subtest(5, 1);
return a + b;
}
// DLLB
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
MessageBoxA(NULL, "DLL B attach.", "DLL B", MB_OK);
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
MessageBoxA(NULL, "DLL B detach.", "DLL B", MB_OK);
break;
}
return TRUE;
}
输出顺序:
PS:如果用显示调用,要注意 ,dllA 卸载 dllB 后,不可以再调用 dllB 的方法,否则会引起崩溃问题。