VS中动态库的创建和调用

VS中动态库的创建和调用

是写好的现有的,成熟的,可以复用的代码。库的存在形式本质上来说库是一种可执行代码的二进制。

​ 库有两种:静态库(.a、.lib)和动态库(.so、.dll)。所谓静态、动态是指链接阶段,静态库的链接阶段是在项目编译的时候静态链接。动态库是在程序运行的时候由代码加载链接。

​ 静态库和动态库的区别主要是在链接阶段处理库的方式不同而区分的。

静态库

概念

​ 静态库指的是在链接阶段直接将库和目标文件一起打包成可执行文件的方式所使用的库就称为静态库。

体现形式

​ .a 或者 .lib 文件

优缺点

优点 :①使可执行文件依赖项少,已经被打包到可执行文件中了。 ②编译阶段完成链接,执行期间代码装载速度快

缺点:①使可执行文件变大。②若作为其他库的依赖库,将会造成多余的副本,因为必须与目标文件打包。③升级不方便,升级必须重新编译

静态库的创建
  1. 使用VS创建一个空项目;
  2. 创建空项目之后将项目设置为静态库(点击项目 -> 属性 -> 常规 -> 配置类型)中修改;
  3. 配置项目lib输出位置(常规 -> 输出目录 :指的是dll输出的文件位置);
  4. 书写接口,在静态库中,只要是可以允许访问的函数和类都可以被使用,没有特别的函数导入和导出。

例程:

#pragma once
#include <iostream>

class Arithmetic
{
public:
    // Returns a + b
    static double Add(double a, double b);//可以调用

    // Returns a - b
    static double Subtract(double a, double b);//可以调用

    // Returns a * b
    static double Multiply(double a, double b);//可以调用

    // Returns a / b
    static double Divide(double a, double b);//可以调用

    void fun2();//可以调用

private:
    static void fun();//不可以调用
    void fun1();//不可以调用
};

#include "Arithmetic.h"

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;
}

void Arithmetic::fun2() {
    std::cout << "公共  void Arithmetic::fun2()" << std::endl;
}

void Arithmetic::fun() {
    std::cout << "私有  static void Arithmetic::fun()" << std::endl;
}
void Arithmetic::fun1() {
    std::cout << "私有  void Arithmetic::fun1()" << std::endl;
}
静态库的调用
  1. 创建一个项目
  2. 配置项目属性,导入静态库位置。
  3. 导入头文件:C/C++ -> 常规 -> 附加包含目录 :指的是需要使用的自己编写的头文件
  4. 导入库文件:链接器 -> 常规-> 附加库目录 :指的是在调用的时候声名需要使用的lib文件。
  5. 添加导入lib名称:链接器 -> 输入 -> 附加依赖项 :指的是在调用的时候声名需要使用的lib文件。
  6. 引入库的头文件,之后直接使用库即可。

动态库

概念

动态库指的是在程序运行过程中动态加载库的方式使用的库,也就是动态库的链接是发生在程序运行时期的,它和可执行文件是分开的,只是可执行文件在运行的某个时期调用了它。

体现形式

​ .DLL、.lib 和 .a 、.so ;

优缺点

好处:程序自身的体积不会因为动态函数库变大。
缺点:就是程序运行过程中使用到了这些函数库内的功能时,万一系统特定的位置没有对应的动态库。就会造成程序崩溃或者各种奇怪的问题。

动态库的创建

在介绍动态库的创建之前,我们先来了解以下的宏。

#pragma once
#ifdef PUBFUN_EXPORTS
#define PUBUTIL_DLL __declspec(dllexport)
#else
#define PUBUTIL_DLL __declspec(dllimport)
#endif

MSVC编译器提供了一系列C/C++的扩展来指定符号的导入导出,即__declspec属性关键字。

dllexport与dllimport存储级属性是微软对C和C++的扩展,可用于从dll中导入或导出函数、数据、对象(objects)

__declspec(dllexport) 表示该符号是从本DLL导出的符号。

__declspec(dllimport) 表示该符号是从别的DLL中导入的。

我们在创建动态库的时候需要用到上面的宏。

创建方式1:使用空项目

  1. 使用VS创建一个空项目;
  2. 创建空项目之后将项目设置为动态库(点击项目 -> 属性 -> 常规 -> 配置类型)中修改;
  3. 配置项目lib 和 DLL 输出位置(常规 -> 输出目录 :指的是dll输出的文件位置);
  4. 创建一个header.h (此文件名可以自由定义)定义之后将上面的宏写入到文件中(宏名称可以自己定义)。
  5. 使用定义的宏定义动态库导出的函数或者类。
  6. 编译生成动态库。

例程:

创建动态库导出导入宏

//header.h
#pragma once
#ifdef BD_TEST
#define BDTEXT_DLL __declspec(dllimport)
#else
#define BDTEST_DLL __declspec(dllexport)
#endif

使用宏定义导出的函数

//testDLL.h
#pragma once
#include "header.h"

int  BDTEXT_DLL add(int a, int b);

导出函数功能的实现

//testDLL.cpp
#include "testDLL.h"

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

编译:

在这里插入图片描述
这就是最后编译出来的lib和dll库。

创建方式2:直接创建动态库项目

使用直接创建动态库项目,会在项目中生成一个dllMain.cpp的文件。如下:

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.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;
}

根据微软官网说明:

DllMain是动态链接库 (DLL) 的可选入口点。 当系统启动或终止进程或线程时,它将使用进程的第一个线程为每个加载的 DLL 调用入口点函数。 使用 LoadLibraryFreeLibrary 函数加载或卸载 DLL 时,系统还会调用 DLL 的入口点函数。

之后其他的接口函数和接口类和空项目的建立是一样的。

动态库的调用
  1. 创建一个项目
  2. 导入头文件:C/C++ -> 常规 -> 附加包含目录 :指的是需要使用的自己编写的头文件
  3. 导入库文件:链接器 -> 常规-> 附加库目录 :指的是在调用的时候声名需要使用的lib文件。
  4. 添加导入lib名称:链接器 -> 输入 -> 附加依赖项 :指的是在调用的时候声名需要使用的lib文件。
  5. 引入库的头文件,之后直接使用库即可。
  6. 将于lib配套的dll放到执行文件exe所在的文件目录下。

例程:

配置头文件

在这里插入图片描述

配置lib文件位置

在这里插入图片描述

配置需要使用lib文件

在这里插入图片描述

配置完成之后编写代码

#include <iostream>
#include <testDLL.h>//引入头文件

int main() {

	std::cout << add(2, 5) << std::endl; //调用库中的函数
	getchar();
	return 0;
}

注意点:

1、没有设置为导出的函数名称或者类,无法在外部调用dll使用。导出的函数和类必须使用导出宏修饰。

项目常见配置项

常规 -> 输出目录 :指的是dll输出的文件位置

常规 -> 中间目录 :指的是中间件的输出位置

常规 -> 配置类型 :指的是项目类型

VC++目录 -> 包含文件 :指的是三方库文件的头文件位置

VC++目录 -> 库目录 : 指的是三方库文件(.dll .lib)文件

C/C++ -> 常规 -> 附加包含目录 :指的是需要使用的自己编写的头文件

C/C++ -> 预处理器 -> 预处理器定义 : 指的是我们需要配置的宏定义

链接器 -> 输入 -> 附加依赖项 :指的是在调用的时候声名需要使用的lib文件。

链接器 -> 高级 -> 导入库 : 指的是lib导出的文件位置

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

VUE指令(一)

vue会根据不同的指令&#xff0c;针对不同的标签实现不同的功能。指令是带有 v- 前缀的特殊标签属性。指令的职责是&#xff0c;当表达式的值改变时&#xff0c;将其产生的连带影响&#xff0c;响应式地作用于 DOM。 1、v-text&#xff1a;设置元素的文本内容&#xff0c;不会解…

Vulnhub-HACKSUDO: PROXIMACENTAURI渗透

文章目录 一、前言1、靶机ip配置2、渗透目标3、渗透概括 开始实战一、信息获取二、端口敲门三、web密码爆破四、getShell五、获取新用户六、提权 一、前言 由于在做靶机的时候&#xff0c;涉及到的渗透思路是非常的广泛&#xff0c;所以在写文章的时候都是挑重点来写&#xff0…

TypeScript类型挑战:实现内置的Omit实用类型

掌握 TypeScript Omit 泛型&#xff0c;一起完成 Type 挑战&#xff0c;巩固 TypeScript 知识。 为了帮助读者更好地巩固 TypeScript 的知识&#xff0c;我从 Github 上的 type-challenges 库中选择了几十个挑战&#xff0c;与您一起完成类型挑战。 挑战 实现内置的 Omit&…

初识Ubuntu

其实还是linux操作系统 命令都一样 但是在学习初级阶段&#xff0c;我还是将其分开有便于我的学习和稳固。 cat 查看文件 命令 Ubuntu工作中经常是用普通用户&#xff0c;在需要时才进行登录管理员用户 sudn -i 切换成管理用户 我们远程连接时 如果出现 hostname -I没有出现…

什么是数字身份?

数字身份是指代表在线实体的数据集合。数字身份可以代表用户、组织或电子设备&#xff0c;由他们的帐户、凭证、证书、行为和使用模式组成。在身份访问管理&#xff08;IAM&#xff09;中&#xff0c;需要数字身份来对用户进行身份验证并授予他们访问敏感数据的权限。 数字身份…

5、MAE:探索视觉预训练模型

目录 1、论文 2、背景与动机 3、回答的问题 4、创新与卖点 5、实现细节 模型框架 具体步骤 简单代码示例 6、一些资料 1、论文 Masked Autoencoders Are Scalable Vision Learnershttps://arxiv.org/pdf/2111.06377.pdf 2、背景与动机 在深度学习和计算机视觉的领域中…

【uniapp】新课uniapp零基础入门到项目打包(微信小程序/H5/vue/安卓apk)全掌握

一、uniapp和HBuilderX介绍 uni-app官方网站&#xff1a;https://uniapp.dcloud.net.cn/ 为什么要学习uniapp&#xff1f; 1、一套代码可以打包到不同的应用平台&#xff1b;一套代码编到十几个平台&#xff0c;这不是梦想。眼见为实&#xff0c;扫描以下二维码&#xff0c;…

2023年全国职业院校技能大赛软件测试赛题—单元测试卷⑧

单元测试 一、任务要求 题目1&#xff1a;根据下列流程图编写程序实现相应处理&#xff0c;执行j10*x-y返回文字“j1&#xff1a;”和计算值&#xff0c;执行j(x-y)*(10⁵%7)返回文字“j2&#xff1a;”和计算值&#xff0c;执行jy*log(x10)返回文字“j3&#xff1a;”和计算值…

Qt / day04

1. 思维导图 2. 编写程序实现闹钟如下 文件 代码 clock.h #include "clock.h" #include "ui_clock.h"Clock::Clock(QWidget *parent): QWidget(parent), ui(new Ui::Clock), ptrTimerShow(new QTimer(this)), ptrTimerAlarm(new QTimer(this)), ptrSpeec…

Spark六:Spark 底层执行原理SparkContext、DAG、TaskScheduler

Spark底层执行原理 学习Spark运行流程 学习链接&#xff1a;https://mp.weixin.qq.com/s/caCk3mM5iXy0FaXCLkDwYQ 一、Spark运行流程 流程&#xff1a; SparkContext向管理器注册并向资源管理器申请运行Executor资源管理器分配Executor&#xff0c;然后资源管理器启动Execut…

iOS rootless无根越狱解决方案

据游戏工委数据统计&#xff0c;2023年国内游戏市场实际销售收入与用户规模双双创下新高&#xff0c;游戏普遍采用多端并发方式&#xff0c;成为收入增长的主因之一。 中国市场实际销售收入及增长率丨数据来源&#xff1a;游戏工委 多端互通既是机遇&#xff0c;也是挑战。从游…

使用 Docker 和 Diffusers 快速上手 Stable Video Diffusion 图生视频大模型

本篇文章聊聊&#xff0c;如何快速上手 Stable Video Diffusion (SVD) 图生视频大模型。 写在前面 月底计划在机器之心的“AI技术论坛”做关于使用开源模型 “Stable Diffusion 模型” 做有趣视频的实战分享。 因为会议分享时间有限&#xff0c;和之前一样&#xff0c;比较简…

MySQL篇—通过Clone插件进行远程克隆数据(第三篇,总共三篇)

在介绍 Clone 最终篇之前&#xff0c;我们先简要回顾一下前面所讲的内容。在第一篇中&#xff0c;我们探讨了 Clone 的用途、使用的前提条件、存在的限制&#xff0c;以及它的备份原理。Clone 是一种用于复制和备份数据的工具&#xff0c;它能够快速高效地创建数据的精确副本。…

超维空间M1无人机使用说明书——53、ROS无人机二维码识别与降落——V2升级版本

引言&#xff1a;使用二维码引导无人机实现精准降落&#xff0c;首先需要实现对二维码的识别和定位&#xff0c;可以参考博客的二维码识别和定位内容。本小节主要是通过获取拿到的二维码位置&#xff0c;控制无人机全向的移动和降落&#xff0c;本小节再V1版本的基础上增加了动…

【AI视野·今日NLP 自然语言处理论文速览 第七十二期】Mon, 8 Jan 2024

AI视野今日CS.NLP 自然语言处理论文速览 Mon, 8 Jan 2024 Totally 17 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computation and Language Papers DeepSeek LLM: Scaling Open-Source Language Models with Longtermism Authors DeepSeek AI Xiao Bi, Deli Ch…

【修图】AI修图工具

人脸替换 免费的人脸替换工具&#xff1a; Face Swap&#xff1a; https://vmodel.ai/face-swap 支持单人换脸、多人换脸 AI消除 SnapEdit https://snapedit.app/remove-object 不付费的话只能下载清晰度较低的版本 但我试了几个在线的AI消除工具&#xff0c;SnapEdit算是…

最新版docker-compose安装

Ubuntu/Kali 下载安装最新版 docker-compose # FastGit加速 sudo curl -L "https://hub.fgit.cf/docker/compose/releases/download$(curl -L -i -s -o /dev/null -w "%{url_effective}\n" https://hub.fgit.cf/docker/compose/releases/latest | awk -F tag …

docker-compose部署kafka、SASL模式(密码校验模式)

一.基础kafka部署 zookeeper&#xff0c;kafka&#xff0c;kafka-ui docker-compose.yml 注意点&#xff1a;192.168.1.20 是宿主机的ip version: "3" services:zookeeper:image: wurstmeister/zookeepercontainer_name: zookeeperrestart: alwaysports:- 2181:2…

【python】python新年烟花代码【附源码】

欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 新年的钟声即将敲响&#xff0c;为了庆祝这个喜庆的时刻&#xff0c;我们可以用 Python 编写一个炫彩夺目的烟花盛典。本文将详细介绍如何使用 Pygame 库创建一个令人惊叹的烟花效果。 一、效果图&#xff1a; 二…

质量好洗地机有哪些?洗地机口碑榜

在很多人眼中&#xff0c;洗地机可能被简单地视为一种高价的拖把&#xff0c;但作为一个经验丰富的洗地机测评博主&#xff0c;我要强调洗地机在家务工作中的巨大价值。它不仅仅是一种清洁工具&#xff0c;更是集扫地、拖地、洗地以及擦干地板等多项功能于一身的强大设备。通过…