0%

Windows核心编程 - DLL基础

最近在学习 Win32编程,所以顺便将每日所学记录下来,一方面为了巩固学习的知识,另一方面也为同样在学习Win32开发的童鞋们提供一份参考。

本系列博文均根据学习《Windows核心编程》一书总结而来;

运行环境:

  • 操作系统: Windows 10家庭版
  • 编译器:Visual Studio 2019

DLL基础

DLL与进程的地址空间

DLL只是一组源代码模块,每个模块包含了执行文件或另一个要调用的一组函数。再应用程序中能够调用DLL中函数之前,DLL文件映像必须被加载到调用进程的地址空间中。一旦DLL的文件映像被映射到进程的地中空间中,DLL的函数就可以供进程中的所有线程使用;

DLL运行总体情况

隐式链接是常用的链接类型。

若要创建一个从DLL模块输入函数和变量的执行模块,必须创建一个DLL模块;

  • 首先创建一个头文件,它包含想从DLL输出的函数原型、结构和符号;DLL的所有源代码必须包含该头文件;
  • 创建一个或多个C++源代码模块,用于实现想在DLL中实现的函数和变量;
  • 编译产生.obj文件
  • 链接.obj文件
  • 如果有导出函数,那么连接程序会生成一个.lib文件。
  • 引用.lib文件,必须包含头文件

创建静态库模块

demo01:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//MyAdd.h
#pragma once
extern "C" _declspec(dllexport) int Add(int a, int b);
extern "C" _declspec(dllexport) int Sub(int a, int b);

//MyAdd.cpp
#include "pch.h"
#include "MyAdd.h"

int Add(int x, int y)
{
return x + y;
}

int Sub(int x, int y)
{
return x - y;
}

调用这个静态库:

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
#include <Windows.h>
#pragma comment(lib,"StaticLib1.lib") //调用静态库
#include "MyAdd.h"
int main()
{
int z = Add(10, 20);
printf("z = %d\n", z);
getchar();
return 0;
}

创建动态模块

动态库中的代码和上面我们创建静态库相同:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//DLL的显式加载
#include <Windows.h>
#include <tchar.h>
#include <stdio.h>
#include <iostream>
using namespace std;
typedef int (*pFunction)(int, int);
int main()
{
HINSTANCE hLib;
hLib = ::LoadLibrary(TEXT("DllTest.dll"));
pFunction add = (pFunction)::GetProcAddress(hLib, "Plus");
cout << add(2, 3) << endl;
getchar();
return 0;
}