静态库与动态库的基本介绍


  动态库与静态库的区别在于可执行程序生成时的链接阶段,如下图所示:
  在这里插入图片描述

静态库

静态库的特点

  静态库具有以下特点:

  • 静态库对函数库的链接实在编译时期完成的。
  • 程序在运行时与函数库再无瓜葛,移植方便。
  • 浪费空间资源,因为所有相关的目标文件与涉及到的函数库都被链接合成一个可执行文件。
  • 如果静态库更新了,所有使用它的应用程序都需要重新编译、发布给用户。

  其中第三点揭示了静态库的重要缺陷:如果静态库被多个程序所使用,那么有多少个程序就会又多少个拷贝。

静态库的使用

  注:以下静态库与动态库的使用均默认在visual studio上。

创建

  首先在vs上创建一个Win32控制台应用程序,选择生成静态库。
  不像动态库可能需要使用关键字_declspec(dllexport),生成静态库的代码和普通代码并无区别。

/******************StaticMath.h********************/
#pragma once
class StaticMath
{
public:
	StaticMath();
	~StaticMath();

	static int add(int a, int b);
	static int sub(int a, int b);
	static int mul(int a, int b);
	static int div(int a, int b);
};

/******************StaticMath.h********************/
#include "StaticMath.h"

StaticMath::StaticMath()
{
}


StaticMath::~StaticMath()
{
}

int StaticMath::add(int a, int b)
{
	return a + b;
}

int StaticMath::sub(int a, int b)
{
	return a - b;
}

int StaticMath::mul(int a, int b)
{
	return a*b;
}

int StaticMath::div(int a, int b)
{
	return a / b;
}

  右键项目生成静态库.lib即可。

使用

  在vs中使用静态库时,主要有以下三项设置:

  1. VC++目录-》包含目录:设置静态库头文件所在目录;
  2. VC++目录-》库目录:设置静态库所在目录;
  3. 输入-》附加依赖项:设置需要链接的静态库名称(因为静态库目录已设置,所以这里只需要补充静态库名称即可,需要带后缀:*.lib)。

  经过以上设置,我们就可以在代码中正常调用静态库中的函数了。

  此外,还有一种方式可以省略上述配置操作:

#pragma comment ( lib,"wpcap.lib" ) 
#include "stdafx.h"
#include <StaticMath.h>
#include <iostream>

using namespace std;

int main()
{
	int a = 10;
	int b = 2;

	cout << "+:" << StaticMath::add(a, b) << endl;
	cout << "-:" << StaticMath::sub(a, b) << endl;
	cout << "*:" << StaticMath::mul(a, b) << endl;
	cout << "/:" << StaticMath::div(a, b) << endl;


    return 0;
}

动态库

动态库的特点

  动态库具有以下特点:

  • 动态库在编译时不会被链接到目标代码中,而是在程序运行时才会载入。
  • 不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的示例,规避了空间浪费。
  • 如果动态库更新了,更新动态库即可,增量更新。

动态库的使用

创建

  首先在vs上创建一个Win32控制台应用程序,选择生成动态库。工程创建后,会生成dllmain.cpp,作为定义 DLL 应用程序的入口点。我们不用理会。

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

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
	case DLL_PROCESS_DETACH:
		break;
	}
	return TRUE;
}

  但在定义需要导出的函数时,与静态库有所不同,需要使用关键字_declspec(dllexport)。示例如下:

/******************DynamicMath.h********************/
#pragma once
class DynamicMath
{
public:
	__declspec(dllexport) DynamicMath();
	__declspec(dllexport) ~DynamicMath();

	static __declspec(dllexport) int add(int a, int b);
	static __declspec(dllexport) int sub(int a, int b);
	static __declspec(dllexport) int mul(int a, int b);
	static __declspec(dllexport) int div(int a, int b);
};

/******************DynamicMath.cpp********************/
#include "DynamicMath.h"
DynamicMath::DynamicMath()
{
}

DynamicMath::~DynamicMath()
{
}

int DynamicMath::add(int a, int b)
{
	return a + b;
}

int DynamicMath::sub(int a, int b)
{
	return a - b;
}

int DynamicMath::mul(int a, int b)
{
	return a*b;
}

int DynamicMath::div(int a, int b)
{
	return a / b;
}

  然后右键项目生成即可。

使用

  需要注意的是,通过上述步骤,我们在生成动态库dll文件的同时,还生成了同名lib文件,
  静态库当然只能使用静态加载,但是动态库则可以选择静态加载或者动态加载。

静态加载

  动态库的静态加载和静态库的静态加载设置方式基本相同,唯一需要注意的是需要将dll拷贝到exe运行目录。
  那么这里存在一个疑问,为什么使用动态库时还需要一个lib?这里的lib和静态库有何区别?

静态库对应的lib文件叫静态库,动态库对应的lib文件叫【导入库】。实际上静态库本身就包含了实际执行代码、符号表等等,而对于导入库而言,其实际的执行代码位于动态库中,导入库只包含了地址符号表等,确保程序找到对应函数的一些基本地址信息。

动态加载

  动态库的动态加载在配置时十分简单,我们只要能够确保程序能够找到这些动态库即可。重点是在代码的实现部分。示例如下:
在这里插入图片描述
  其中主要涉及到三个函数:LoadLibrary、GetProcAddress、FreeLibrary。关于这三个函数的详细使用可访问:链接
  而在Qt平台下,则主要使用QLibrary类完成动态加载。

参考链接

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值