C++静态和动态链接库导出和使用

1、简介

代码开发过程中会遇到很多已有的函数库,这些函数库是现有的,成熟的,可以复用的代码。现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。

本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。库有两种:静态链接库和动态链接库。

动态链接库包含了函数所在的DLL文件和函数入口等相关信息,代码由运行时加载在进程空间中的DLL提供,显示调用不需要仅需要动态链接库的dll文件,无需头文件.h和动态链接库.lib文件,隐式调用则需要上述三种文件。
动态库特点:

  • 动态库把对一些库函数的链接载入推迟到程序运行时期。
  • 可以实现进程之间的资源共享。(因此动态库也称为共享库)
  • 将一些程序升级变得简单。
  • 甚至可以真正做到链接载入完全由程序员在程序代码中控制(显示调用)

静态链接库包含了函数实现本身,在编译的时候直接将代码放入程序中。在调用静态链接库的时,需要使用静态链接库的头文件.h以及静态链接库的.lib文件。

静态库特点:

  • 静态库对函数库的链接是放在编译时期完成的
  • 程序在运行时与函数库再无瓜葛,移植方便。
  • 浪费空间和资源,因为所有相关的目标文件与牵涉到的函数库被链接合成一个可执行文件
  • 如果静态库进行更新则应用该库的所有程序都需要重新编译(全量更新)。

2、Windows动态链接库使用

2.1 动态链接库生成

首先新建工程MathLibrary_dll,在源文件中添加MathLibrary.cpp,在头文件中添加MathLibrary.h,具体代码如下:

  • 添加头文件MathLibrary.h如下:
#pragma once#ifndef MATHLIBRARY
#define MATHLIBRARY#ifdef MATHLIBRARY_EXPORTS
#define MATHLIBRARY_API __declspec(dellexport)
#else
#define MATHLIBRARY_API __declspec(dllimport)
#endif // MATHLIBRARY_EXPORTSnamespace MathLibrary {class MATHLIBRARY_API Arithmetic{public:Arithmetic();~Arithmetic();// Returns a + bdouble Add(double a, double b);// Returns a - bdouble Subtract(double a, double b);// Returns a * bdouble Multiply(double a, double b);// Returns a / bdouble Divide(double a, double b);private:};extern "C" MATHLIBRARY_API double power(double a, double ratio);
}
#endif // !MATHLIBRARY
  • 添加源文件MathLibrary.cpp
// MathLibrary.cpp
// compile with: cl /c /EHsc MathLibrary.cpp
// post-build command: lib MathLibrary.obj#include "MathLibrary.h"
#include<math.h>namespace MathLibrary
{Arithmetic::~Arithmetic() {};Arithmetic::Arithmetic() {};double Arithmetic::Add(double a, double b){return a + b;}double Arithmetic::Subtract(double a, double b){return a - b;}double Arithmetic::Multiply(double a, double b){return a * b;}double Arithmetic::Divide(double a, double b){return a / b;}double power(double a, double ratio) {return pow(a, ratio);}
}
  • 生成动态链接库
    在项目的配置属性页选择配置类型为动态库(.dll)
    在这里插入图片描述
    生成的DLL文件如下所示:
    在这里插入图片描述

2.2 动态链接库使用

  • 新建测试动态链接库的项目MathLibrary_dll_test,并在源文件中添加一个测试代码如下所示:
#include <iostream>
#include "MathLibrary.h"
using namespace MathLibrary;int main()
{double a = 7.0;int b = 99;double ratio = 2.0;Arithmetic *demo_class = new Arithmetic();std::cout <<"Add结果为= " << demo_class->Add(a, b) << std::endl;std::cout << "Multiply结果为= " << demo_class->Multiply(a, b) << std::endl;std::cout << "Divide结果为= " << demo_class->Divide(a, b) << std::endl;std::cout << "Subtract结果为= " << demo_class->Subtract(a, b) << std::endl;std::cout << "power结果为= " << power(a,ratio) << std::endl;delete demo_class;return 0;
}
  • 环境配置包括三步

1、属性页->C\C+±>附加包含目录,添加头文件目录
在这里插入图片描述
2、属性页->链接器->附加库目录中,添加lib文件目录
在这里插入图片描述
3、属性页->链接器->输入->附加依赖项,添加MathLibrary_dll.lib
在这里插入图片描述

  • 运行测试程序,结果正常显示如下:
    在这里插入图片描述

3、Windows静态链接库使用

3.1 静态链接库生成

首先新建工程MathLibrary,在源文件中添加MathLibrary.cpp,在头文件中添加MathLibrary.h,具体代码如下:

  • 添加头文件MathLibrary.h如下:
#pragma oncenamespace MathLibrary {class Arithmetic{public:Arithmetic();~Arithmetic();// Returns a + bstatic double Add(double a, double b);// Returns a - bstatic double Subtract(double a, double b);// Returns a * bstatic double Multiply(double a, double b);// Returns a / bstatic double Divide(double a, double b);private:};
}
  • 添加源文件MathLibrary.cpp
#include "MathLibrary.h"namespace MathLibrary
{Arithmetic::~Arithmetic() {};Arithmetic::Arithmetic() {};double Arithmetic::Add(double a, double b){return a + b;}double Arithmetic::Subtract(double a, double b){return a - b;}double Arithmetic::Multiply(double a, double b){return a * b;}double Arithmetic::Divide(double a, double b){return a / b;}
}
  • 设置属性页并生成静态链接库
    在这里插入图片描述
    生成的静态lib文件如下所示:
    在这里插入图片描述

3.2 静态链接库使用

  • 新建测试静态链接库的项目MathLibrary_test,并在源文件中添加一个测试代码test.cpp如下所示:
#include <iostream>
#include "MathLibrary.h"int main()
{double a = 7.4;int b = 99;std::cout << "a + b = " <<MathLibrary::Arithmetic::Add(a, b) << std::endl;std::cout << "a - b = " <<MathLibrary::Arithmetic::Subtract(a, b) << std::endl;std::cout << "a * b = " <<MathLibrary::Arithmetic::Multiply(a, b) << std::endl;std::cout << "a / b = " <<MathLibrary::Arithmetic::Divide(a, b) << std::endl;return 0;
}
  • 环境配置
    在属性页->VC++目录->包含目录,添加头文件地址
    在属性页->VC++目录->库目录,添加库文件地址
    在这里插入图片描述
    在属性页->链接器->输入->附加依赖项,添加静态库lib名称MathLibrary.lib
    在这里插入图片描述
  • 运行测试程序,结果正常显示如下:
    在这里插入图片描述
    以上就是windows系统上使用visual studio 2019进行静态库和动态库的生成和使用说明,仅作记录。

参考:
https://blog.csdn.net/htt789/article/details/81454832
https://www.cnblogs.com/skynet/p/3372855.html
https://learn.microsoft.com/zh-cn/cpp/build/walkthrough-creating-and-using-a-dynamic-link-library-cpp?view=msvc-170
——END——

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/2943.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机器学习笔记 - Facebook AI Similarity Search(Faiss)简介

一、概述 Facebook AI Similarity Search (Faiss)是高效相似性搜索最受欢迎的轮子之一。给定一组向量,我们可以使用 Faiss 对它们进行索引——然后使用另一个向量(查询向量),我们在索引中搜索最相似的向量。 它包含搜索任何大小的向量集的算法,除非超出RAM的大小。它还包…

【完美复现】面向配电网韧性提升的移动储能预布局与动态调度策略【IEEE33节点】(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

EFS文件夹加密属性灰色不能勾选怎么办?

EFS加密是Windows自带的文件夹加密方式&#xff0c;对于用户而言&#xff0c;它的加密是无感的。但是有些时候我们会发现EFS的加密选项为灰色&#xff0c;且无法勾选&#xff0c;那么这时该怎么办呢&#xff1f; 使用EFS加密的条件 首先&#xff0c;要使用EFS加密功能并不是没…

华为智能高校出口安全解决方案(1)

华为智能高校出口安全解决方案&#xff08;1&#xff09; 视频链接方案背景需求分析高校园区网概述高校园区网全景高校出口场景介绍高校出口整体需求分析业务安全需求攻击防御需求运维审计需求 方案规划华为智能高校出口安全解决方案架构华为智能高校出口安全解决方案功能划分业…

总结vue3 的一些知识点:​Vue3 起步

目录 引言 Vue3 混入 实例 选项合并 实例 实例 全局混入 实例 Vue3 起步 Vue 3.0 实例 data 选项 实例 方法 总结 引言 Vue 进阶系列教程将在本号持续发布&#xff0c;一起查漏补缺学个痛快&#xff01;若您有遇到其它相关问题&#xff0c;非常欢迎在评论中留言讨…

Linux终端与进程的关系 ( 1 ) -【Linux通信架构系列】

系列文章目录 C技能系列 Linux通信架构系列 C高性能优化编程系列 深入理解软件架构设计系列 高级C并发线程编程 期待你的关注哦&#xff01;&#xff01;&#xff01; 现在的一切都是为将来的梦想编织翅膀&#xff0c;让梦想在现实中展翅高飞。 Now everything is for the…

CleanMyMac X中文版Mac电脑系统清理工具使用测评

有些人可能会说&#xff0c;mac系统根本就不需要清理&#xff0c;但是真正到你磁盘快满的时候就不是这种想法了&#xff0c;不管什么系统&#xff0c;它都会缓存一些系统、用户等文件&#xff0c;可能当时能够帮上大忙&#xff0c;能够在操作的时候更快、更便捷&#xff0c;但是…

『 MySQL篇 』:MySQL 锁机制介绍

目录 一. 概述 二. 全局锁 三 . 表级锁 三. 行级锁 一. 概述 锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中&#xff0c;除传统的计算资源&#xff08;CPU、RAM、I/O&#xff09;的争用以外&#xff0c;数据也是一种供许多用户共享的资源。如何保证数据…

【八股】【C++】函数与类

这里写目录标题 形参与实参的区别函数调用过程指针和引用当函数参数引用作为函数参数有哪些好处回调函数友元函数重载匹配运算符重载直接初始化与拷贝初始化函数指针C中struct&#xff08;结构&#xff09;和class&#xff08;类&#xff09;的区别C有哪几种构造函数构造函数的…

云HIS是什么?HIS系统为什么要上云?云HIS有哪些优点?

一、当前医疗行业HIS的现状与发展趋势 1.医院信息系统&#xff08;HIS&#xff09;经历了从手工到单机再到局域网的两个阶段&#xff0c;随着云计算、大数据新技术迅猛发展&#xff0c;基于云计算的医院信息系统将逐步取代传统局域网HIS , 以适应人们对医疗卫生服务越来越高的要…

【day4】类和对象

#include <iostream> using namespace std;class Complex {int real;int vir; public:Complex(){}Complex(int a,int b):real(a),vir(b){}void show(){cout << real << "" << vir << "i" << endl;}//成员函数版的运算…

spark12-13-14

12. Task线程安全问题 12.1 现象和原理 在一个Executor可以同时运行多个Task&#xff0c;如果多个Task使用同一个共享的单例对象&#xff0c;如果对共享的数据同时进行读写操作&#xff0c;会导致线程不安全的问题&#xff0c;为了避免这个问题&#xff0c;可以加锁&#xff…