源码路径:dangwei-90/DllLoadAndFree (github.com)
DLL显式调用的加载和卸载顺序:DLL的加载和卸载顺序 (显式调用)_二七-CSDN博客
dll 分为显式加载和隐式加载。
假设 program 加载 dllA , 而dllA 加载 dllB, 隐式加载顺序如下:
1. program 启动
2. dllB 被加载
3. dllA 被加载
这样是为了保证 dllA 被加载时,一定是可用的,所以会先加载 dllA 所依赖的 dllB。
同理,隐式卸载顺序如下:
1. dllA 被卸载
2. dllB 被卸载
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;
}
// DLLA, 加载 dllB
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#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;
}
以此输出: