多次LoadLibrary,只有第一次会真正加载,后面一直驻留在EXE内存中。
只要不调用FreeLibrary,DLL一直都在。
后面的LoadLibrary等同于空操作。
具体原理参考:进程EXE、DLL加载到内存中的过程 https://blog.csdn.net/calmreason/article/details/84404293
CllDLL.cpp
#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include <string>
#include <functional>
using namespace std;
void f()
{
string str = "Win32DLL.dll";
HMODULE libraryHandle = ::LoadLibrary(str.c_str());
if (libraryHandle != NULL)
{
typedef int (WINAPI* EXECUTOR_FUNC)(void);
typedef function<void(void)> Handler;
EXECUTOR_FUNC function = (EXECUTOR_FUNC)GetProcAddress(libraryHandle, "fnWin32DLL");
if (function)
{
cout << function() << endl;
}
else
{
cout << "can not find function " << endl;
}
}
else
{
cout << "can not loadlibrary!" << endl;
}
}
int main()
{
f();
f();
return 0;
}
DLL.cpp
// Win32DLL.cpp : 定义 DLL 应用程序的导出函数。
//
#include "stdafx.h"
#include "Win32DLL.h"
#include <iostream>
#include <string>
using namespace std;
// 这是导出变量的一个示例
WIN32DLL_API int nWin32DLL=0;
class A
{
public:
A(const string& id = ""):m_id(id) { cout << "A("<<m_id<<")" << endl; }
~A() { cout << "~A(" << m_id << ")" << endl; }
private:
string m_id;
};
A a("a in global");
// 这是导出函数的一个示例。
WIN32DLL_API int fnWin32DLL(void)
{
A a("a in fnWin32DLL");
return 42;
}
// 这是已导出类的构造函数。
// 有关类定义的信息,请参阅 Win32DLL.h
CWin32DLL::CWin32DLL()
{
return;
}
输出:
A(a in global)
A(a in fnWin32DLL)
~A(a in fnWin32DLL)
42
A(a in fnWin32DLL)
~A(a in fnWin32DLL)
42
~A(a in global)
请按任意键继续. . .
可以看出两次LoadLibrary只创建了一个global对象,并在EXE退出的时候释放了这个global对象。
另参考:DLL中对象的构造与析构 https://blog.csdn.net/calmreason/article/details/83957799