此教程在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.编译运行

创作不易,多多点赞哟~

参考了下面两位大佬的教程。在此感谢。

DLL教程 - 如何编写动态链接库_动态链接库怎么写-CSDN博客

VS2022环境下C++ DLL动态链接库的编写和调用_vs2022 如何引入dll库-CSDN博客

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐