二进制入门学习笔记-5.静/动态连接库)

1.静态链接库(Static Library)

1.0 简介

为了方便代码复用,所以将代码打包成静态链接库方便自己和他人进行复用。静态链接库使用时,本质上是将其编译到exe文件当中去,这种编译方式如果需要修改静态链接库中函数的功能,那么整个项目都需要重新编译。

1.1 生成一个静态链接库

编写一个testlib.cpp文件,其中实现所需要的各种函数,如下:

//testlib.cpp
#include "testlib.h"
int plus(int x,int y){
    return x+y;
}

头文件中添加testlib中实现函数的声明,如下:

//testlib.h
int plus(int x,int y);

之后直接编译即可生成一个testlib.lib的静态链接库文件。此时保存好.lib.h文件以便之后引用此静态链接库。

1.2 静态链接库的使用

此时就需要先将lib文件和头文件复制到项目所在的目录下,然后进行引入。引入静态链接库有如下两种方法,第一种方法如下:

#include "stdafx.h"
#include "testlib.h"    //引入静态链接库头文件
#pragma comment(lib,"testlib.lib")   //引入lib文件
int main(int argc, char* argv[])
{
    int a=0;
    a = plus(1,2);
    printf("%d",a);
    return 0;
}

方法二:在项目设置->连接当中加入所要用的静态链接库文件名

2.动态链接库

2.1.新建一个动态链接库

2.1.1 一般方法

首先新建一个动态链接库testdll,在testdll.cpp文件当中写入如下内容:

#include "testdll.h"
int __stdcall Plus(int x,int y){//一般动态链接库会选用stdcall使用内平栈。
    return x+y;
}

在testdll.h中进行声明:文件内容如下:

extern "C" __declspec(dllexport) __stdcall int Plus(int x,int y)

以上代码中extern表示这个是个全局函数,“C”表示要按照C的方式去导出,__declspec(dllexport)告诉编译器这不是一个普通的函数是一个dll。

2.1.2 使用def文件创建

1.写一个正常的函数,如下:

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

2.头文件中写入如下内容:

int Plus(int x,int y);

3.写一个*.def文件

EXPORTS

Plus @12 NONAME

使用上述这种方式可以将函数的名称隐藏起来。更加安全。

2.2 使用动态链接库

2.2.1 隐式链接

  • 1.将*.dll文件*.lib文件拷贝到工程目录下面
  • 2.将# pragma comment(lib,"testdll.dll")添加到调用文件中
  • 3.加入函数的声明,如:extern "C" __declspec(dllimport) __stdcall int Plus(int x,int y);
#include "stdafx.h"
#pragma comment(lib,"testdll.lib")
extern "C" __declspec(dllimport) __stdcall int Plus(int x,int y);
int main(int argc, char* argv[])
{
    printf("%d",Plus(1,2));
}

2.2.2 显示链接

1.定义函数指针

typedef int (__stdcall *lpPlus)(int,int);

2.声明函数指针变量

lpPlus myPlus;

3.动态加载dll到内存中

HINSTANCE hModule = LoadLibrary("DllDemo.dll");

注:

  • 1.Handle代表系统的内核对象,如文件句柄、线程句柄、进程句柄
  • 2.HMODULE代表应用程序载入的模块
  • 3.HINSTANCE在win32下与HMODULE是相同的东西,这是WIN16遗留
  • 4.HWND是窗口句柄
  • 5.这些东西都是无符号整形的编号,主要是为了方便区分。

4.获取函数地址

myPlus=(lpPlus)GetProcAddress(hModule,"Plus");

5.调用函数。

int res=myPlus(1,2);

完整代码如下:

// testadddll.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h>
int main(int argc, char* argv[])
{
    typedef int (__stdcall *lpPlus)(int,int);
    lpPlus myPlus;
    HINSTANCE hModule = LoadLibrary("testdll.dll");
    myPlus=(lpPlus)GetProcAddress(hModule,"_Plus@8");
    int res=myPlus(1,2);
    printf("%d",res);
    return 0;
}