你真的懂动态库吗?一文详解动态库的方方面

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

这里写目录标题

创建动态库

1.【新建】-》【项目】-》【动态链接库】
在这里插入图片描述
新建的动态库结构如下
在这里插入图片描述
新建项目MathLibrary.h

// MathLibrary.h - Contains declarations of math functions
#pragma once

#ifdef MATHLIBRARY_EXPORTS
#define MATHLIBRARY_API __declspec(dllexport)
#else
#define MATHLIBRARY_API __declspec(dllimport)
#endif

// The Fibonacci recurrence relation describes a sequence F
// where F(n) is { n = 0, a
//               { n = 1, b
//               { n > 1, F(n-2) + F(n-1)
// for some initial integral values a and b.
// If the sequence is initialized F(0) = 1, F(1) = 1,
// then this relation produces the well-known Fibonacci
// sequence: 1, 1, 2, 3, 5, 8, 13, 21, 34, ...

// Initialize a Fibonacci relation sequence
// such that F(0) = a, F(1) = b.
// This function must be called before any other function.
extern "C" MATHLIBRARY_API void fibonacci_init(
	const unsigned long long a, const unsigned long long b);

// Produce the next value in the sequence.
// Returns true on success and updates current value and index;
// false on overflow, leaves current value and index unchanged.
extern "C" MATHLIBRARY_API bool fibonacci_next();

// Get the current value in the sequence.
extern "C" MATHLIBRARY_API unsigned long long fibonacci_current();

// Get the position of the current value in the sequence.
extern "C" MATHLIBRARY_API unsigned fibonacci_index();

注意头文件中的预定义宏

#ifdef MATHLIBRARY_EXPORTS
#define MATHLIBRARY_API __declspec(dllexport)
#else
#define MATHLIBRARY_API __declspec(dllimport)
#endif

在动态库设置预定义宏
在这里插入图片描述
添加项目MathLibrary.cpp

// MathLibrary.cpp : Defines the exported functions for the DLL.
#include "pch.h" // use stdafx.h in Visual Studio 2017 and earlier
#include <utility>
#include <limits.h>
#include "MathLibrary.h"

// DLL internal state variables:
static unsigned long long previous_;  // Previous value, if any
static unsigned long long current_;   // Current sequence value
static unsigned index_;               // Current seq. position

// Initialize a Fibonacci relation sequence
// such that F(0) = a, F(1) = b.
// This function must be called before any other function.
void fibonacci_init(
	const unsigned long long a,
	const unsigned long long b)
{
	index_ = 0;
	current_ = a;
	previous_ = b; // see special case when initialized
}

// Produce the next value in the sequence.
// Returns true on success, false on overflow.
bool fibonacci_next()
{
	// check to see if we'd overflow result or position
	if ((ULLONG_MAX - previous_ < current_) ||
		(UINT_MAX == index_))
	{
		return false;
	}

	// Special case when index == 0, just return b value
	if (index_ > 0)
	{
		// otherwise, calculate next sequence value
		previous_ += current_;
	}
	std::swap(current_, previous_);
	++index_;
	return true;
}

// Get the current value in the sequence.
unsigned long long fibonacci_current()
{
	return current_;
}

// Get the current index position in the sequence.
unsigned fibonacci_index()
{
	return index_;
}

相关文献
演练创建和使用自己的动态链接库 (C++)

创建静态库

具体参见《演练创建并使用静态库》这里不再详述。

动态库与静态库的区别

名称不同
静态库.lib
动态库
.dll

链接方式不同
静态库采用静态链接方式在程序链接阶段静态库与汇编生成的目标文件一起打包到程序可执行文件*.exe中。
静态库对函数库的链接是在编译阶段完成的运行时与函数库没有关系了。
所有的目标文件和函数库都会链接到程序可执行文件中比较浪费空间和资源。

动态库在编译时并不会被链接到目标代码中而是在程序运行的时候才被载入。
动态链接方式==》动态链接又包括显示链接和隐士链接。

多个程序引用
当一个静态库A被多个程序使用时每个程序都会有A的一个拷贝比较浪费空间。
不同程序使用相同的动态库动态库在内存中只有一份实例可以实现进程之间资源共享。==》动态库也叫做共享库。

程序更新
如果静态库更新了所有使用它的程序都需要重新编译。

注意
静态库的lib和动态库的lib不是一个概念
静态库的lib叫做静态库动态库里面的lib叫做导入库。
静态库lib包含实际执行代码和符号表等导入库实际执行代码在动态库中导入库只包含了地址符号表等。

相关文献
C++静态库与动态库

动态链接与静态链接的区别

相关文献
深入浅出静态链接和动态链接

动态库的加载过程

dll的创建以及应用程序隐式链接到dll的过程

  1. 头文件中包含导出函数的原型、结构和符号的说明
  2. c/c++源文件其中包含待导出函数的实现和变量
  3. 编译器为每个源文件生成.obj文件
  4. 链接器将为每个obj模块合并生成dll
  5. 如果至少导出一个函数或变量链接器同时生成lib文件
    构建exe
  6. 头文件包含导出函数的原型、结构和符号的声明
  7. 源文件包含待导出函数的实现和变量
  8. 编译器为每个源文件生成obj文件
  9. 链接器将每个obj模块合并并使用lib文件来解析导入的函数/变量的引用从而生成exe。它包含一个导入表其中列出了必需的dll和导入的符号
    运行应用程序
    加载程序创建地址空间
    加载程序将必需的dll载入到地址空间
    进程的主线程开始执行应用程序开始执行

dll的创建以及应用程序显示链接到dll的过程

  • 头文件中包含导出函数的原型、结构和符号的说明
  • c/c++源文件其中包含待导出函数的实现和变量
  • 编译器为每个源文件生成.obj文件
  • 链接器将为每个obj模块合并生成dll
  • 如果至少导出一个函数或变量链接器同时生成lib文件显示链接没有用到这个lib文件
    构建exe
  • 头文件包含导出函数的原型、结构和符号的声明
  • 源文件包含待导出函数的实现和变量
  • 编译器为每个源文件生成obj文件
  • 链接器将每个obj模块合并从而生成exe。由于没有直接引用dll的导入符号因此这里不需要它的lib文件生成的exe不包含导入表
    运行应用程序
  • 加载程序创建地址空间 进程的主线程开始执行应用程序开始执行
  • 线程调用loadLiberay来将dll载入到进程的地址空间中。
  • 各个线程可以调用GetProAddress来简接地引用dll导出的符号。

动态库的二进制兼容性

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6