C++动态链接库DLL制作

DLL简介

动态链接库DLL,它是一种可重用的代码和数据的集合,可以由多个应用程序同时使用,与静态链接库不同,动态链接库在运行时加载到内存中,以供应用程序使用。
DLL具有以下优点:

可重用性:由于多个应用程序可以共享一个DLL,因此它们可以共享相同的代码和数据,从而提高了代码的可重用性。
节省内存:由于DLL在运行时才加载到内存中,因此它们可以在不占用过多内存的情况下提供所需的功能。
易于更新:当需要更新DLL时,只需替换现有的DLL文件即可,而无需重新编译使用该DLL的应用程序。
动态链接:DLL在运行时才链接到应用程序中,因此它们可以在应用程序启动后动态加载,从而提高了应用程序的启动速度。
稳定性:由于多个应用程序共享相同的DLL,因此如果DLL中的代码或数据发生问题,则可以在一次更新后修复所有使用该DLL的应用程序。

DLL中导出函数的3种声明方式

在这里插入图片描述
在这里插入图片描述

C++制作DLL文件

制作dll文件
<DllTest.h>

#pragma once
#ifdef MYLIBRARY_EXPORTS
#define MYLIBRARY_API __declspec(dllexport)
#else
#define MYLIBRARY_API __declspec(dllimport)
#endif
 
extern "C" MYLIBRARY_API int Add(int a, int b);

注:extern “C” 只是解决了c与c++编译器之间的兼容问题,如果需要和其他编译器之间兼容,可靠的办法还是增加一个.def文件.
<DllTest.cpp>

#include "pch.h"
#include "DllTest.h"

int Add(int a, int b)
{
    
    
	return a + b;
}

<Source.def>

LIBRARY DllTest
EXPORTS
Add @1

调用dll及测试

//main.cpp
#include "..\\DllTest\DllTest.h"
#include <iostream>
#include <Windows.h>
#pragma comment(lib, "..\\x64\\Release\\DllTest\\DllTest.lib")
using namespace std;

typedef int(*AddFunc)(int, int);

int main()
{
    
    
    //调用__declspec(dllexport)定义的接口
	int a = Add(1, 200);
	printf("a=%d\n", a);
	//调用def定义的接口
	HINSTANCE hinstLib = LoadLibrary(TEXT("..\\x64\\Release\\DllTest\\DllTest.dll"));
	if (hinstLib != NULL)
	{
    
    
		AddFunc add = (AddFunc)GetProcAddress(hinstLib, "Add");
		if (add != NULL)
		{
    
    
			// 调用 DLL 中的函数
			int result = add(1, 2);
			std::cout << "b=" << result << std::endl;
		}
	}
	else
	{
    
    
		cout << "hinst is null" << endl;
	}

	system("pause");
	return 0;
}

在这里插入图片描述
从上面可以看到,通过def定义的接口在调用时比较麻烦,需要定义被调用函数的指针。因此,通常情况下会采取第一种方式设计接口,当然,为了便于后续维护以及解决编译器兼容问题也可以将def文件一并写好。

DllMain函数是必须的吗

DllMain简介
跟exe有个main或者WinMain入口函数一样,DLL也有一个入口函数,就是DllMain。以“DllMain”为关键字,来看看MSDN帮助文档怎么介绍这个函数的。
The DllMain function is an optional method of entry into a dynamic-link library (DLL) 。(简要翻译:对于一个Dll模块,DllMain函数是可选的。)这句话很重要,很多初学者可能都认为一个动态链接库肯定要有DllMain函数。其实不然,像很多仅仅包含资源信息的DLL是没有DllMain函数的。
何时调用DllMain
系统是在什么时候调用DllMain函数的呢?静态链接时,或动态链接时调用LoadLibrary和FreeLibrary都会调用DllMain函数。DllMain的第三个参数fdwReason指明了系统调用Dll的原因,它可能是DLL_PROCESS_ATTACH、DLL_PROCESS_DETACH、DLL_THREAD_ATTACH和DLL_THREAD_DETACH。以下从这四种情况来分析系统何时调用了DllMain。具体可参考这篇博客

[1] C++编写DLL的方法
[2] C++Windows动态库【.DLL文件】制作方法总结
[3] C++动态链接库-06-DLL中.def文件的使用
[4] DLL文件_DLLMain函数详解

猜你喜欢

转载自blog.csdn.net/qq_44924694/article/details/133124626