19.2 显式加载/隐式加载--《Windows核心编程》
部分笔记来自于:https://blog.csdn.net/blade1080/article/details/81364161
注:关于DLL存放位置,一般是放到可执行文件的目录下。
下面时加载程序的搜索顺序:
1) 包含可执行映像文件的目录。 2) 进程的当前目录。 3) Windows系统目录。 4) Windows目录。 5) PATH环境变量中列出的各个目录。
显式加载
调用 LoadLibrary/LoadLibrary 函数加载DLL。
隐式加载
是在系统启动时一次性把所有的DLL的导出函数加载到可执行文件中,需要用到.h和.lib文件。
创建DLL动态库
1、新建Dll项目
文件->新建->项目->Visual C++ win32控制台程序(填写项目名MyDll)->下一步->(应用程序类型)勾选:DLL,(附加选项)勾选:空项目->完成
2、添加新建项MyDll.h
#pragma once
#ifdef MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endif
class MyDll
{
public:
MYDLL_API int Add(int a, int b); // 导出函数
MYDLL_API void myPrint(const char* s);
};
extern "C" MYDLL_API void printStr(const char* s);
extern "C" MYDLL_API extern int num; // 导出变量
dllimport 与 dllexport用于声明导入导出属性,其中_declspec(dllexport)用在dll程序中,用于说明这是导出的函数。而_declspec(dllimport)用在调用dll的程序中,用于说明这是从dll中导入的函数。
3、添加新建项MyDll.cpp
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include "MyDll.h"
#include <iostream>
int num = 10; // 定义变量
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
int MyDll::Add(int a, int b)
{
return a + b;
}
void MyDll::myPrint(const char* s)
{
std::cout << s << std::endl;
}
void printStr(const char* s)
{
std::cout << s << std::endl;
}
4、编译生成
生成结果如下所示
隐式加载方式将使用到MyDll.h、MyDll.lib、MyDll.dll。
MyDll.lib需放置于项目的库搜索路径下,MyDll.dll需放置于项目生成的可执行文件同一目录下。
隐式加载方式使用DLL动态库
隐式加载是在系统启动时一次性把所有的DLL的导出函数加载到可执行文件中,需要用到.h和.lib文件。隐式加载的步骤为:
1、新建测试项目
文件->新建->项目->Visual C++ win32控制台程序(填写项目名testDll)->下一步-> (附加选项)勾选:空项目->完成
2、添加新建项main.cpp文件
注意包含DLL相关的那个头文件
#include <iostream>
#include "MyDll.h" // dll对应的那个头文件
// 在项目属性中添加dll对应.lib路径,附加依赖项里添加dll对应的.lib文件名
// 或者 #pragma comment (lib,"D:/Project Files/MyDll/Debug/MyDll.lib")
int main(void)
{
MyDll test;
std::cout << test.Add(2, 5) << std::endl;
test.myPrint("Func myPrint()");
printStr("Func printStr()");
printf("num = %d", num);
return 0;
}
3、项目属性中添加头文件路径
或者:将头文件拷贝至项目文件同一目录下,即项目默认的头文件搜索路径中。
4、项目属性中添加dll对应.lib路径
5、项目属性中附加依赖项里添加dll对应的.lib文件名
步骤4、5可使用以下代码替代。其中的路径可以使用相对路径(这里为绝对路径)。
#pragma comment (lib,"D:/Project Files/MyDll/Debug/MyDll.lib")