隐式链接

  1. 用特殊声明 _declspec(dllexport) 定义一个导出函数
1
2
3
4
5
6
7
8
9
10
11
#include "stdafx.h"

_declspec(dllexport) long square (long x) // 导出标记
{
return x * x;
}

BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
return TRUE;
}
  1. 编译、链接, 生成.Dll文件和.Lib文件,并拷贝到客户端目录

  2. 工程设置里,exe 关联 .Lib 文件

    注:是源文件所在目录,而不是Debug文件夹

  3. 使用特殊声明 _declspec(dllimport) 声明导出函数并调用

1
2
3
4
5
6
7
8
9
10
11
12
13
#include "stdafx.h"
#include <iostream>
using namespace std;

_declspec(dllimport) long square(long x); // 导入标记

int main(int argc, char* argv[])
{
int x;
cin >> x;
cout << square(x) << endl;
return 0;
}

显示链接

  1. 定义一个函数:bool __stdcall square(long x);
1
2
3
4
5
6
7
8
9
10
11
#include "stdafx.h"

long _stdcall square (long x)
{
return x * x;
}

BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
return TRUE;
}
  1. 通过 .def 文件导出函数并防止函数名被修饰。
1
2
3
4
5
LIBRARY	"dll1"

EXPORTS
square @1
;函数 [@序号]

dll 文件放在 exe 运行目录下(例如:Debug)

  1. 通过3个API函数直接调用.DLL中的导出函数。
    • HMODULE LoadLibrary(LPCTSTR lpFileName); // 获取 dll 句柄
    • FARPROC GetProcAddress(HMODULE hModule, LPSCTR lpProcName); // 加载 dll 函数
    • BOOL FreeLibrary(HMODULE hModule); // 释放 dll 空间
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include "stdafx.h"
#include <iostream>
#include <windows.h>
using namespace std;

typedef long (_stdcall * LF) (long);

int main(int argc, char* argv[])
{

HMODULE hModule = LoadLibrary("dll1");
if (!hModule)
{
cout << "NONE HMODULE" << endl;
return -1;
}

LF lf = (LF) GetProcAddress(hModule, "square");
if (!lf)
{
cout << "NONE FUNCTION" << endl;
return -1;
}

int x;
cin >> x;
cout << lf(x) << endl;

FreeLibrary(hModule);

return 0;
}