此教程在Visual Studio 2022 版本下实现。
主要讲解动态链接库的创建和使用。
DLL文件的调用方式有两种,一种是动态调用,一种是静态调用。
下面会分别介绍两种调用方式。
一、创建动态库项目:
1.新建动态库项目:
这里取名DynamicLibrary。
2.删除多余预编译文件
默认生成好几个预编译文件.
pch.h
pcn.cpp
framework.h
和一个dllmain.cpp文件.
我们可以把没用的预编译文件删除。
先在setting里面设置不使用预编译,然后删除预编译文件。
dllmain.cpp虽然移除也可以work, 但是建议保留,里面有DLL入口函数DllMain。
3.添加代码源文件
然后我们通过右键工程->添加->新建项,选择.h和.cpp分别创建我们的代码文件。
这里取名DynamicLibrary.h/DynamicLibrary.cpp
DynamicLibrary.h
#pragma once
extern "C" int __declspec(dllexport) add(int a, int b);
DynamicLibrary.cpp
int add(int a, int b)
{
return a + b;
}
DynamicLibrary项目是这个样子:
4.编译生成dll文件
最后右键生成,默认会在<工程目录>\x64\Debug下生成DynamicLibrary.dll和DynamicLibrary.lib.
该lib文件不同于<https://blog.csdn.net/weixin_43758311/article/details/133955852>中的静态库文件,此lib文件只是dll文件中导出函数的声明和定位信息,并不包含函数的实现(而第一节中的静态库文件,包含了函数的实现),因此此lib文件只是在调用对应dll库的工程编译时使用,不需要随exe发布。
二、创建动态调用DLL项目:
1.新建控制台应用项目,方便调试。
这里取名DynamicLibraryLoader.
2.添加代码源文件
DynamicLibraryLoader.cpp
#include <iostream>
#include "windows.h"
typedef int (*lpAddFun)(int, int);//宏定义函数指针类型
int main()
{
std::cout << "Hello World!\n";
HINSTANCE hDll;//DLL 句柄
lpAddFun addFun;//函数指针
hDll = LoadLibrary(L"DynamicLibrary.dll");//动态获取dll文件的路径
if (hDll != nullptr)
{
addFun = (lpAddFun)GetProcAddress(hDll, "add");//根据函数名在dll文件中获取该函数的地址
if (addFun != nullptr)
{
int result = addFun(2, 3);
printf("2+3=%d", result);
}
FreeLibrary(hDll);
}
return 0;
}
DynamicLibraryLoader项目是这个样子:
3.拷贝DynamicLibrary.dll文件到DynamicLibraryLoader.exe所在目录
我这里这两个工程放在了同一个sln下面,所以输出目录是相同的,省略这一步。
4.编译运行
三、创建静态调用DLL项目:
1.新建控制台应用项目,方便调试。
这里取名DynamicLibraryLoader2.
2.在DynamicLibraryLoader2里设置编译依赖(依赖于DynamicLibrary)。
2.1头文件依赖
这里我们直接在代码里声明了DLL中的函数,所以省略这一步。
如果是include DynamicLibrary.h 文件的话,就需要设置头文件依赖。
但是这样的话需要改DynamicLibrary.h代码,在同一份.h文件分别声明dllexport和dllimport函数,用宏隔离。请自行研究,不做赘述。 代码大概是这样子:
#pragma once
#ifdef DLL_NEW_EXPORT
#define DLL_NEW_API __declspec(dllexport)
#else
#define DLL_NEW_API __declspec(dllimport)
#endif
#ifdef __cplusplus
extern "C" {
#endif
int DLL_NEW_API add(int a, int b);
#ifdef __cplusplus
}
#endif
2.2lib文件依赖,这里包含lib目录和lib文件名。
lib目录依赖:
lib文件依赖:
这一步是可选的。因为经过测试,将DynamicLibrary.lib文件设置到连接器附加依赖项,和代码里面指定lib文件名#pragma comment (lib,"DynamicLibrary.lib"),两者只需做其中一个。
3.添加代码源文件
在自动创建的DynamicLibraryLoader2.cpp里面添加我们的使用代码。
DynamicLibraryLoader2.cpp
#include <iostream>
//.lib文件中仅仅是关于其对应DLL文件中函数的定位信息
#pragma comment(lib,"DynamicLibrary.lib")
extern "C" int __declspec(dllimport) add(int a, int b);
int main()
{
std::cout << "Hello World!\n";
int result = add(2, 3);
printf("2+3=%d", result);
return 0;
}
DynamicLibraryLoader2项目是这个样子:
4.编译运行
创作不易,多多点赞哟~
参考了下面两位大佬的教程。在此感谢。