windows编程: 动态库(dll)与静态库(lib)的编写与使用

648 阅读3分钟

静态库

静态库是一种在编译时链接到应用程序中的库文件。与动态链接库(DLL)不同,静态库的代码在编译时被复制到最终生成的可执行文件中。以下是静态库的一些关键特点:

静态库的编写

新建项目,选择静态库

image.png

编写头文件

#pragma once

#include <stdio.h>

extern "C"  void StaticHello();

编写实现函数

#include "pch.h"
#include "TestStaticHello.h"


void StaticHello()
{

	printf("Hello World\n");


}

使用静态库

准备工作

重新生成(注意生成的是release还是debug的,X86X64的),这里我选择生成release的.拷贝出两个文件:

  • 我们自己编写的头文件TestStaticHello.h 到自定义的目录my_include
  • release生成的lib文件StaticLib1.lib 到自定义的目录my_lib

添加库头文件

右键属性配置属性 -> C/C++ -> 常规 -> 附加包含目录 中添加我们自定义的my_include

image.png

添加lib依赖

右键,属性.在配置属性 -> 连接器 -> 常规 -> 附加包含目录 中添加my_lib 目录

image.png

右键,属性.在配置属性 -> 连接器 -> 输入 -> 附加依赖项 中添加我们的lib名StaticLib1.lib

image.png

代码使用

#include "TestStaticHello.h"


int main() {


    StaticHello();

    return 0;
}

动态链接库

动态链接库(Dynamic Link Library,简称 DLL)是一种包含可由多个程序共享的代码和数据的文件。与静态库不同,动态链接库在程序运行时被加载,而不是在编译时嵌入到可执行文件中.

动态链接库的编写

打开visual studio,选择新建项目动态链接库

image.png

编写头文件

#pragma once

#ifdef __cplusplus
extern "C" {
#endif

	__declspec(dllexport) int Add(int a, int b);

#ifdef __cplusplus
}
#endif

编写实现

#include "pch.h"
#include "HelloDllHeader.h"

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

额外的,window进行dll的加载时,会调用入口函数:

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include <iostream>

BOOL APIENTRY DllMain(HMODULE hModule,
	DWORD  ul_reason_for_call,
	LPVOID lpReserved)
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
	{
		// DLL 加载
		printf("DLL_PROCESS_ATTACH \n");
		break;
	}

	case DLL_THREAD_ATTACH:
	{	
		// 线程加载
		printf("DLL_THREAD_ATTACH \n");
		break;
	}
	case DLL_THREAD_DETACH:
	{
		// 线程卸载
		printf("DLL_THREAD_DETACH\n");
		break;
	}
	case DLL_PROCESS_DETACH:
	{
		// DLL 卸载
		printf("DLL_PROCESS_DETACH \n");
		break;
	}
	}
	return TRUE;
}

这里可以自定义在dll加载时候触发,或者dll卸载时候触发.

动态链接库的使用

visual studio 中,使用dll的方式有两种,一种是像静态库一样,配置头文件目录,lib目录,lib的文件名. 然后通过引入的方式来进行调用.与静态链接库的区别是.dll文件需要与exe文件放置在同目录.另一种是不需要头文件,也不需要.lib文件,只需要.dll文件. 利用LoadLibrary来进行dll的加载,利用GetProcAddress来获取函数的地址.

#include <iostream>
#include <windows.h>

int main() {

	// 加载 DLL
	HMODULE hDll = LoadLibrary(L"TestDllDemo.dll");
	if (!hDll) {
		std::cerr << "Could not load the DLL!" << std::endl;
		return 1;
	}

	// 获取函数地址
	typedef int (*AddFunc)(int, int); // 定义函数指针类型
	AddFunc Add = (AddFunc)GetProcAddress(hDll, "Add");

	if (!Add) {
		std::cerr << "Could not locate the function!" << std::endl;
		FreeLibrary(hDll); // 释放 DLL
		return 1;
	}

	// 调用函数
	int result = Add(5, 3);
	std::cout << "Result: " << result << std::endl;

	// 释放 DLL
	FreeLibrary(hDll);
	return 0;
}

至于函数名,结构.可以使用静态分析工具来对dll的导出函数进行分析得到.

3.jpg