【09】C++实战篇——C++ 生成静态库.lib 及 C++调用lib,及实际项目中的使用技巧

文章目录

  • 1 C++ 静态库.lib 生成
    • 1.1 静态库lib的生成方法和使用方法
    • 1.2 创建静态库项目
    • 1.3 编写.h 和 .cpp文件
    • 1.4 设置 及 生成 DLL
  • 2 调用 C++ 静态库lib
    • 2.1 新建LIBtest及测试代码
    • 2.2 静态库配置 及代码调用测试
  • 3 实际项目中的使用技巧、及通用设置
    • 3.1 设置lib输出路径
    • 3.2 设置头文件引入路径
    • 3.3 改进后 测试
  • 4 完整代码.h文件、.cpp 文件
  • 5 完整项目文件下载

1 C++ 静态库.lib 生成

C++ 静态库.lib 生成C++ 动态库.dll生成方法基本一样,【08】C++实战篇——C++ 生成动态库.dll 及 C++调用DLL,及实际项目中的使用技巧

不同的就是 配置类型-->动态库( .dll) 改为 配置类型-->静态库(.lib)

为了验证效果,使用三种方法导出函数:

  • //导出函数
  • //导出类
  • //以C方式导出函数

1.1 静态库lib的生成方法和使用方法

  • 创建静态库lib
创建静态库lib:1.VS创建C++ 空项目MyLIB:编写.h和.cpp文件在.h文件中宏定义导出图数2.生成1ib文件:右键项目-->属性-->配置类型-->静态库(.lib)以Debug x64 生成解决方案
  • 使用静态库lib
VS创建C++ 空项目LIBtest使用静态库lib:隐式调用:1..lib(MyLIB.lib).h(mathTest.h)文件放到工程目录下(LIBtest项目的.cpp同目录下)2.项目右键-- > 属性-->配置属性-->链接器-->输入->附加依项-- > 添加MyLIB.lib3.#include mathTest.h4.代码调用

1.2 创建静态库项目

1.VS创建C++ 空项目MyLIB
在这里插入图片描述

1.3 编写.h 和 .cpp文件

添加 mathTest.hmathTest.cpp文件
在这里插入图片描述

mathTest.h

#pragma once
#ifndef MATHTEST_H
#define MATHTEST_H//宏定义导出:
#ifndef MATHTEST_ //如果没有定义 MATHTEST_,就定义MATHTEST_API __declspec(dllexport)
#define MATHTEST_API __declspec(dllexport) //导出
#else
#define MATHTEST_API __declspec(dllimport) //导入
#endif//导出函数
MATHTEST_API int add(int a, int b);//加法
MATHTEST_API int subtract(int a, int b);//减法//导出类
class MATHTEST_API mathTest
{public:int multiply(int a, int b);//乘法int divide(int a, int b);//除法
};//以C方式导出函数
//extern "C",告诉编译器这里是C语言代码//为了使自己建的库可以在 C/C++ 通用调用,使用 __cplusplus ,
//当C++调用代码时,__cplusplus 值为1,声明函数外面就加了一层“extern "C" {}”;
//当C 调用代码时,__cplusplus 值为0,就相当于没有“extern "C" {}”;#ifdef __cplusplus 
extern "C"
{
#endifMATHTEST_API int Cadd(int a, int b);//加法MATHTEST_API int Csubtract(int a, int b);//减法
#ifdef __cplusplus
}
#endif#endif

mathTest.cpp

#include "mathTest.h"/*创建静态库lib:1.VS创建C++ 空项目MyLIB:编写.h和.cpp文件在.h文件中宏定义导出图数2.生成1ib文件:右键项目-->属性-->配置类型-->静态库(.lib)以Debug x64 生成解决方案
*///导出函数
int add(int a, int b)//加法
{return a + b;
}
int subtract(int a, int b)//减法
{return a - b;
}//导出类
int mathTest::multiply(int a, int b)//乘法
{return a * b;
}int mathTest::divide(int a, int b)//除法
{return a / b;
}//以C方式导出函数
//extern "C",告诉编译器这里是C语言代码
int Cadd(int a, int b)//加法
{return a + b;
}int Csubtract(int a, int b)//减法
{return a - b;
}

1.4 设置 及 生成 DLL

右键项目–>属性–>配置类型–>静态库( .lib)
在这里插入图片描述

右键项目–>生成 (如修改后,可以点重新生成)

成功:
在这里插入图片描述
查看 生成的lib文件
在这里插入图片描述

2 调用 C++ 静态库lib

VS创建C++ 空项目LIBtest使用静态库lib:隐式调用:1..lib(MyLIB.lib).h(mathTest.h)文件放到工程目录下(LIBtest项目的.cpp同目录下)2.项目右键-- > 属性-->配置属性-->链接器-->输入->附加依项-- > 添加MyLIB.lib3.#include mathTest.h4.代码调用

2.1 新建LIBtest及测试代码

右键“解决方案MyLIB”,新建C++ 空项目LIBtest
在这里插入图片描述
在这里插入图片描述

在项目中添加main.cpp文件,及代码
在这里插入图片描述

#include<iostream>
#include"mathTest.h"
using namespace std;/*
VS创建C++ 空项目LIBtest使用静态库lib:隐式调用:1.把.lib(MyLIB.lib)、.h(mathTest.h)文件放到工程目录下(LIBtest项目的.cpp同目录下)2.项目右键-- > 属性-->配置属性-->链接器-->输入->附加依项-- > 添加MyLIB.lib3.#include mathTest.h4.代码调用
*/int main()
{//调用dll导出的函数int sum = add(10, 5);int sub = subtract(10, 5);//调用dll导出的类成员函数mathTest mathT; //实例化对象int mul = mathT.multiply(10, 5);int div = mathT.divide(10, 5);//调用以C方式导出的函数int Csum = Cadd(10, 5);int Csub = Csubtract(10, 5);cout << "我的静态库.lib调用: " << endl;cout << "add(10,5) = " << sum << endl<< "subtract(10,5) = " << sub << endl<< "multiply(10,5) = " << mul << endl<< "divide(10,5) = " << div << endl<< "Cadd(10,5) = " << Csum << endl<< "Csubtract(10,5) = " << Csub << endl;return 0;
}

2.2 静态库配置 及代码调用测试

使用静态库lib:隐式调用:1..lib(MyLIB.lib).h(mathTest.h)文件放到工程目录下(LIBtest项目的.cpp同目录下)2.项目右键-- > 属性-->配置属性-->链接器-->输入->附加依项-- > 添加MyLIB.lib3.#include mathTest.h4.代码调用

在这里插入图片描述

项目右键-- > 属性–>配置属性–>链接器–>输入->附加依项-- > 添加MyLIB.lib
在这里插入图片描述

在这里插入图片描述

LIBtest“设为启动项”

方法参考下图
在这里插入图片描述
调用测试成功,

导出函数、导出类成员函数、以C方式导出的函数,现在这三种函数都用结果都输出了,说明这三种dll导出函数方式都有,但我们最常用的是 以C方式导出的函 ,这中通用个,避免出错。
在这里插入图片描述

3 实际项目中的使用技巧、及通用设置

(lib、.h复制到 测试项目的.cpp目录下,太麻烦),下面使用自动路径

删掉LIBtest目录下上一次的操作文件 1.把.lib(MyLIB.lib)、.h(mathTest.h)文件放到工程目录下(LIBtest项目的.cpp同目录下)

3.1 设置lib输出路径

直接将lib生成文件,的生路径设为 “LIBtest”项目下的.cpp路径;

为了是的路径通用,这里使用相对路径 ../LIBtest/

在这里插入图片描述

并且将 MyLIB 设为启动项,设置后需要重新生成lib。

可见新的dll文件已经 生成在LIBtest项目下面了

在这里插入图片描述

在这里插入图片描述

3.2 设置头文件引入路径

将LIBtest设为启动项;
设置LIBtest项目的 附加包含目录为 ../MyLIB/这样LIBtest项目就可以访问 mathTest.h 文件了。

在这里插入图片描述

3.3 改进后 测试

再次测试 OK

在这里插入图片描述

注意:既然新的dll生成路径已经更改到 “LIBtest”项目下的.cpp路径,那么第一次在 MyLIB\x64\Debug\路径下生成的生成的lib最好删掉,

不然两个路径同时存在lib,调用时会产生混淆,当两个路径下的lib代码源文件完全一样时,似乎并没有影响。一旦新的lib代码修改了,这时两个路径下lib内容不一致,调用运行时就会出错。

所以下面路径的3文件删掉。
在这里插入图片描述

4 完整代码.h文件、.cpp 文件

为了统一规范,同时使用“以C语言的方式导出函数”

导出函数、导出类成员函数、以C方式导出的函数,现在这三种函数都用结果都输出了,说明这三种dll导出函数方式都有,但我们最常用的是 以C方式导出的函 ,这种通用个,避免出错。

mathTest.h文件

#pragma once
#ifndef MATHTEST_H
#define MATHTEST_H//宏定义导出:
#ifndef MATHTEST_ //如果没有定义 MATHTEST_,就定义MATHTEST_API __declspec(dllexport)
#define MATHTEST_API __declspec(dllexport) //导出
#else
#define MATHTEST_API __declspec(dllimport) //导入
#endif//以C方式导出函数
//extern "C",告诉编译器这里是C语言代码//为了使自己建的库可以在 C/C++ 通用调用,使用 __cplusplus ,
//当C++调用代码时,__cplusplus 值为1,声明函数外面就加了一层“extern "C" {}”;
//当C 调用代码时,__cplusplus 值为0,就相当于没有“extern "C" {}”;#ifdef __cplusplus 
extern "C"
{
#endifMATHTEST_API int Cadd(int a, int b);     //加法MATHTEST_API int Csubtract(int a, int b);//减法MATHTEST_API int Cmultiply(int a, int b); //乘法MATHTEST_API int Cdivide(int a, int b);   //除法#ifdef __cplusplus
}
#endif#endif

mathTest.cpp文件

#include "mathTest.h"/*创建静态库lib:1.VS创建C++ 空项目MyLIB:编写.h和.cpp文件在.h文件中宏定义导出图数2.生成1ib文件:右键项目-->属性-->配置类型-->静态库(.lib)以Debug x64 生成解决方案
*///以C方式导出函数int Cadd(int a, int b)//加法
{return a + b;
}
int Csubtract(int a, int b)//减法
{return a - b;
}int Cmultiply(int a, int b)//乘法
{return a * b;
}int Cdivide(int a, int b)//除法
{return a / b;
}

5 完整项目文件下载

完整项目工程文件,下载后可直接编译运行
在这里插入图片描述

在这里插入图片描述

C++ 生成静态库.lib 及 C++调用lib

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

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

相关文章

飞算JavaAI:从写不出代码到丝滑开发,飞算JavaAI把小白从编程深渊捞进了正轨---它都让我怀疑自己是不是多余的!

开篇介绍 对于很多初学者来说&#xff0c;编程是一项既有趣又充满挑战的任务。面对复杂的代码和繁琐的开发流程&#xff0c;常常会感到无从下手。不过&#xff0c;现在有了飞算JavaAI&#xff0c;这一切都将变得简单起来。 它有啥实用功能呢&#xff1f; 比如&#xff1a; …

关于tresos Studio(EB)的MCAL配置之GtmCfg

Generic Time Module通用时钟模块GeneralGtmCfg_DevErrorDetect开发者错误检测开关GtmCfg_DemErrorReporting诊断错误报告开关GtmCfg_VersionInfoApi获取版本信息的接口开关GtmCfg_ConfigSetClockManagementUnitGlobal_Clock_Control_Numerator全局时钟分频器的分子Global_Cloc…

深入探索Weaviate:构建高效AI应用的数据库解决方案

在当今数据驱动的世界中&#xff0c;高效地存储、检索和处理大规模数据成为了AI应用开发的关键挑战。Weaviate作为一个开源的向量搜索引擎&#xff0c;凭借其强大的功能和灵活的架构&#xff0c;正逐渐成为开发者构建智能AI应用的首选工具。本文将深入探讨Weaviate的核心概念、…

【开源】一款开源、跨平台的.NET WPF 通用权限开发框架 (ABP) ,功能全面、界面美观

文章目录一、开源地址二、框架介绍三、技术路线四、适用场景五、功能模块六、框架演示截图一、开源地址 Gihub地址&#xff1a; https://github.com/HenJigg/wpf-abp B站学习视频&#xff1a;https://www.bilibili.com/video/BV1nY411a7T8?spm_id_from333.788.player.switch&…

信创缓存中间件-TongRDS(Redis平替)安装

TongRDS 是由东方通开发的国产 分布式内存数据缓存中间件&#xff0c;功能类似于 Redis&#xff0c;但它是完全自主研发的国产产品&#xff0c;是国内信创的一大重要组件。它兼容 Redis 的接口&#xff0c;能做到应用代码无需改动即可替换使用。TongRDS是没有直接的下载地址的。…

Git链接备用手册

三板斧及其他&#xff1a;git init&#xff1a;初始化git仓库git add . :将所在文件夹中的所有文件加入到暂存区git commit -m 自定义记录信息 &#xff1a;将暂存区中的数据放到Git的仓库&#xff08;本地&#xff09;中&#xff0c;并进行记录&#xff08;自定义&#xff0…

零信任网络概念及在网络安全中的应用

零信任网络概念及在网络安全中的应用 零信任网络&#xff08;Zero Trust Network&#xff09;是一种颠覆传统边界安全的架构理念&#xff0c;其核心是**“永不信任&#xff0c;始终验证”**&#xff08;Never Trust, Always Verify&#xff09;。它假设网络内外均存在威胁&…

GaussDB case when的用法

1 case函数的类型case具有两种格式&#xff0c;简单case函数和case搜索函数。这两种方式&#xff0c;大部分情况下可以实现相同的功能。1.1 简单case函数语法case column when <condition> then value when <condition> then value ...... else value end;示例case…

Git用法记录

代码中冲突标记的含义&#xff1a;<<<<<<< HEAD 标记当前分支&#xff08;或本地&#xff09;的旧代码作为分隔线 >>>>>>> [commit哈希] 标记从其他分支合并过来的新代码&#xff08;这里的 c472b4b... 是提交哈希&#xff09; 暂存…

解决Android Studio中创建的模拟器第二次无法启动的问题

Android Studio中创建的模拟器&#xff0c;首次启动时一切正常。但是关闭模拟器&#xff0c;下一次启动时一直显示&#xff1a;Connecting to the Emulator&#xff0c;无法启动。无法启动的原因通常是默认开启了模拟器的快速启动功能&#xff0c;首次启动时是“冷启动”&#…

Linux设备驱动架构相关文章

学习一个领域&#xff0c;最好是从多个角度去学习&#xff0c;总有一个角度适合你。学习Linux驱动&#xff0c;从架构的角度把握&#xff0c;比直接看代码更容易接受。以架构为主&#xff0c;结合细节学习&#xff0c;我称之为自上而下的学习方法&#xff0c;就一个字&#xff…

YOLOv13 汉化优化部署版本:超图增强自适应视觉感知的目标检测系统

目录 &#x1f4d6; 项目概述&#x1f680; YOLOv13 核心特性&#x1f4ca; 性能对比&#x1f5bc;️ 可视化效果&#x1f527; 项目优化改进⚙️ 快速部署指南▶️ 运行使用&#x1f4dd; 使用示例&#x1f527; 故障排除&#x1f31f; 项目特色&#x1f517; 相关链接&#…

uni-app webview的message监听不生效(uni.postmessage is not a function)

uni-app开发app web-view组件message事件不触发背景子页面是h5&#xff08;非uni-app版&#xff09;子页面是h5&#xff08;uni-app版&#xff09;背景 大致背景是 在uni-app开发的客户端app中使用web-view嵌入h5页面&#xff0c;在h5中通过postmessage API触发父组件web-view…

【异常案例分析】使用空指针调用函数(非虚函数)时,没有崩溃在函数调用处,而是崩在被调用函数内部

目录 1、问题说明 2、代码段地址与数据段地址 3、使用空指针调用BindWindow函数&#xff08;非虚函数&#xff09;&#xff0c;没有崩在BindWindow函数的调用处&#xff0c;而是崩在函数内部 3.1、虚函数调用的二次寻址 3.2、崩溃在被调用函数内部 4、总结 C软件异常排查…

锁定中科院1区TOP!融合LSTM与Attention做时间序列预测 !

Transformer虽火&#xff0c;但在数据少、要求稳的时序预测场景中&#xff0c;LSTM仍是首选。尤其加上注意力机制后&#xff0c;更是弥补了LSTM的短板&#xff0c;增强了性能&#xff0c;实现了更精确的预测。这种组合不仅应用场景广泛&#xff0c;工业界爱&#xff0c;学术界也…

在不可更改系统上构建数据响应机制的可选策略

在现代企业信息系统架构中&#xff0c;我们常常面临如下挑战&#xff1a;某个业务系统属于“不可变更系统”&#xff0c;我们既不能修改其业务逻辑&#xff0c;也不能对其核心代码做任何侵入式改动。但与此同时&#xff0c;我们又需要对该系统中的某些关键业务数据变更做出响应…

Docker 实战 -- cloudbeaver

文章目录前言文件目录docker-compose.yml网络连接前言 当你迷茫的时候&#xff0c;请点击 Docker 实战目录 快速查看前面的技术文章&#xff0c;相信你总能找到前行的方向 上一篇文章 Docker 实战 – Mysql 讲述了用 docker 搭建 mysql 数据库的过程, 连接数据库的工具很多, …

Rust × WebAssembly 项目脚手架详解

一、模板概览 模板生成方式核心用途典型角色wasm-pack-templatecargo generate …把 Rust 代码 打包成 npm 库「底层算法/组件」作者create-wasm-appnpm init wasm-app构建纯 JS/TS 项目&#xff0c;消费上面生成的 npm 包Web 前端/Node 服务rust-webpack-templatenpm init ru…

RSA 解密逻辑

以下是使用类的方式封装 RSA 解密逻辑&#xff0c;使其更易于调用和管理&#xff1a; from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_v1_5 import base64 class RSADecryptor:"""RSA 解密工具类&#xff0c;封装解密逻辑&#xff0c;方便…

Oracle 19C 在centos中安装操作步骤和说明

1、oracle 一到五&#xff0c;是在centos下&#xff0c;搭建数据的每个具体详细步骤。 oracle:一、环境准备-CSDN博客 oracle:二、centos下安装oracle-CSDN博客 oracle :三、配置LISTEN-CSDN博客 oracle:四、创建数据库-CSDN博客 oracle&#xff1a;五、配置修改-CSDN博客…