C++封装静态链接库和使用
零碎记事
距离上次发博客已经有一年半了,转眼间我也是从做图像研究到了做游戏开发,说起来看看前面的博文,本来就有前兆的东西呢(笑)......因为主要还是在使用虚幻引擎,所以C++的东西会碰到多一些。
以后程序技术方面的文章就放博客,游戏设计相关的杂谈就放知乎那边吧,博主的知乎可以通过友链过去。
B站那边的账号也打算开始复活,后面是更新游戏设计杂谈类的视频还是更新虚幻技术方面的视频还在犹豫不决......
为什么要把程序封装成库
有时我们需要把自己的程序交给第三方调用,但是又不想被别人看到自己的具体实现代码,就封装成库给别人使用。库有动态链接库和静态链接库,区别是动态链接库可以在程序运行时动态链接,而静态链接库相当于.cpp文件,在编译时的链接阶段就链接进去了。
博主的环境
系统:Window 10
IDE:VS2022
如果在使用的是其他IDE的,看完这个其实自己应该也能知道用其他IDE该怎么操作,其实就是一个对编译和链接过程的理解深度的问题,懂了在哪里都能自己封装和使用库的。
这边的演示有中文路径,VS对中文路径支持得确实还挺可以的,不会报错。不过建议大家还是尽量别这样了,就怕万一你那边对中文路径支持不好,编译出问题。
封装步骤
准备好待封装的程序
我准备了一个Point类,就当做是要给别人用的,现在我就把这个类封装成静态库。
//Point.h
#pragma once
#include <utility> typedef std::pair<int, int> Coordinate;
class Point
{
private:
Coordinate location;
public:
Point();
Point(int x, int y);
Coordinate GetLocation();
int GetX() const;
int GetY() const;
virtual Point operator + (const Point& B) const;
virtual Point operator - (const Point& B) const;
};
//Point.cpp
#include "Point.h" Point::Point() :
location(Coordinate(0, 0))
{
} Point::Point(int x, int y):
location(Coordinate(x, y))
{
} Coordinate Point::GetLocation()
{
return location;
} int Point::GetX() const
{
return location.first;
} int Point::GetY() const
{
return location.second;
} Point Point::operator+(const Point& B) const
{
return Point(GetX()+B.GetX(), GetY()+B.GetY());
} Point Point::operator-(const Point& B) const
{
return Point();
}
开始封装
配置项目
平常我们是编译成可执行文件(即.exe),现在我们设置一下,改成编译成静态库(即.lib)。
这个设置在VS2022里是这样的:
右击项目->属性->配置属性->常规->配置类型->改为静态库


这样我们编译出来的东西就不是.exe文件,而是.lib文件了,也就是静态链接库。
编译
这边在VS2022里,编译就是生成。

就跟编译普通程序一样,编译成功。

找到编译好的静态库
自己翻翻项目下面的文件夹,能找到编译出来的静态库的。
我这边是 项目根目录/x64/Debug/项目名.lib,就是下图里的那个Point.lib,这就是静态库。

打包
其实就是把头文件跟静态库一起给别人就行了,静态库的作用跟.cpp文件差不多,使用时就是包含头文件,然后链接到静态库把实现关联起来即可。

使用静态库
使用步骤
包含头文件
新建了个项目,这个项目要用到我的那个Point类,为了方便包含头文件,我把上边的那个有Point.h有和Point.lib的文件夹挪到新项目文件夹下了。

新建了个程序,要用到我写的那个Point类,那就先包含Point.h,里面有关于Point类的声明。
//使用静态库.cpp
#include <iostream>
#include "大摸鱼师千里的Point类/Point.h"
using namespace std; int main()
{
Point a(1, 2);
Point b(3, 4);
Point c = a + b;
cout << c.GetX() << ", " << c.GetY() << endl; return 0;
}
但是这个时候编译还是通不过的,如下图报了“无法解析外部符号”,是链接的错误来的。头文件虽然有Point类声明信息,但没有实现的信息,实现的信息在静态库里,但是现在链接器还找不到静态库,所以报错了。

添加链接路径
有两种方法,一种是在源文件里设置,另一种是在项目里设置。
源文件设置
先讲在源文件里设置,其实就是加个编译头告诉链接器静态库的路径而已,语法如下:
#pragma comment(lib, 你的静态库路径)
这样子链接器在搜索默认的库文件路径外,还会搜你这里的设的静态库路径。
在我这里,加了就是会变成这样:
//使用静态库.cpp
#include <iostream>
#include "大摸鱼师千里的Point类/Point.h"
using namespace std; #pragma comment(lib, "大摸鱼师千里的Point类/Point.lib") int main()
{
Point a(1, 2);
Point b(3, 4);
Point c = a + b;
cout << c.GetX() << ", " << c.GetY() << endl; return 0;
}
因为链接器找到路径了,编译就能过了,程序正常运行,效果如下。

项目设置
VS2022里是这么设置链接器搜索的库目录的
先是设置库的目录,项目属性->VC++目录->库目录->编辑->新行->把静态库所在目录添加进去




因为这个时候只是加了搜索的库目录,但是还没有具体到哪个库,可以像上边那样用编译头来指定,就是不加相对路径直接指定静态库,就像这样。
#pragma comment(lib, "Point.lib")
现在讲怎么在项目里配置具体到指定库。
项目属性->链接器->输入->附加依赖项->编辑->添加你的库



设完就是不加编译头也能编译运行程序了,这是效果

以上就是C++封装库和使用的全部内容了,觉得有学到的话可以点个赞嘿嘿。
搜索
复制
C++封装静态链接库和使用的更多相关文章
- App开发流程之数据持久化和编译静态链接库
先记录数据持久化. iOS客户端提供的常用数据持久化方案:NSUserDefaults代表的用户设置,NSKeydArchiver代表的归档,plist文件存储,SQLite数据库(包括上层使用的Co ...
- linux c静态链接库与动态链接库
库函数是我们编程的时候经常用到的,我们协作编程的时候可以将常用的函数封装成库供大家使用,这样能够提高大家的工作效率.对于库函数,它分为动态链接库和静态链接库.对于静态链接库我们必须是连接到可执行文件中 ...
- dll和lib(包括静态链接库和与dll同时生成的lib)
转:http://blog.csdn.net/galaxy_li/article/details/7411956 1:神马是Dll和Lib,神马是静态链接和动态链接 大家都懂的,DLL就是动态链接库, ...
- 静态链接库(lib)、动态链接库(dll)与动态链接库的导入库(lib)
静态链接库与动态链接库相对应.动态链接库的导入库不同于以上两种库. 1.静态链接库(lib) 程序编译一般需经编辑.编译.连接.加载和运行几个步骤.在我们的应用中,有一些公共代码是需要反复使用 ...
- MFC 封装类为静态链接库
mfc自带的基本控件都不怎么美观,所以一般开发者都会自定义类对控件进行重绘.手里也积累了不少控件的重绘,对对话框.静态文本.列表框等. 但是每次都要把这些类重新导入到新的工程里,比较麻烦,而且我也不想 ...
- vc下的静态链接库与动态链接库(一)
一.静态库与动态库的区别 目前以lib后缀的库有两种,一种为静态链接库(Static Libary,以下简称“静态库”),另一种为动态连接库(DLL,以下简称“动态库”)的导入库(Import Lib ...
- C/C++ 静态链接库(.a) 与 动态链接库(.so)
平时我们写程序都必须 include 很多头文件,因为可以避免重复造轮子,软件大厦可不是单靠一个人就能完成的.但是你是否知道引用的那些头文件中的函数是怎么被执行的呢?这就要牵扯到链接库了! 库有两种, ...
- VS2010编译Boost 1.57 静态链接库
http://www.cnblogs.com/cuish/p/4175491.html 0.前提 Boost库版本 1.57.0 下载地址 http://www.boost.org/users/his ...
- 利用GCC编译器生成动态链接库和静态链接库
转载请标明:http://www.cnblogs.com/winifred-tang94/ 1.编译过程 gcc –fPIC –c xxx.c 其中-fPIC是通知gcc编译器产生位置独立的目标代码. ...
随机推荐
- 133_Power BI 报表服务器2020年1月版本更新亮点
博客:www.jiaopengzi.com 焦棚子的文章目录 请点击下载附件 一个很长的春节假期后,居家办公. 升级了Power BI 报表服务器(2020年1月版本). 具体的升级内容见官网博客: ...
- Java 对象实现 Serializable 的原因
java.io.Serializable 是 Java 中的一种标记接口(marker interface).标记接口是一种特殊的接口,java.io.Serializable 接口没有任何方法,也没 ...
- iOS全埋点解决方案-数据存储
前言 SDK 需要把事件数据缓冲到本地,待符合一定策略再去同步数据. 一.数据存储策略 在 iOS 应用程序中,从 "数据缓冲在哪里" 这个纬度看,缓冲一般分两种类型. 内 ...
- NBMiner42.1版本发布,完全解锁30系LHR版本显卡
2021年下半年,NVIDIA发布了LHR版本显卡,对显卡算力进行了限制. 2022年5月8日,NBMiner发布NBMiner_41.0版本,在最新的内核中加入了100%LHR解锁器,适用于Wind ...
- 『忘了再学』Shell基础 — 21、变量的测试与内容置换
目录 1.什么是变量的测试与内容置换 2.变量的测试与内容置换 3.示例 例1: 例2: 例3: 1.什么是变量的测试与内容置换 我们之前说过,在Shell中,一个变量未定义,和一个变量为空值的输出效 ...
- 广义SAM
参考 还有首先你要会SAM吧~ 用途 相比与单串SAM,广义自动机能存储的是多个字符串. 有两种写法,第一种是离线利用trie树结构,第二种是在线伪广义SAM 离线+Trie 首先构建出trie树. ...
- Maven POM文件介绍
1. POM文件是什么 1.1 Super POM 1.2 Minimal POM 1.3 Effective POM 3. 项目继承 和 项目聚合 2.1 Project Inheritance 项 ...
- Kubernetes将弃用Docker!与 containerd容器引擎
时间戳:2022-06-07 20:32:19 星期二 撰写文档参考:(阿良-腾讯课堂)Kubernetes将弃用Docker 参考博客k8s入坑之路(3)containerd容器 container ...
- jdbc连接数据库问题
### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Fail ...
- Linux shell脚本基础
程序的组成: 程序:算法+数据结构 数据:程序处理的目标 数据结构:相互之间存在一种或多种特定关系的数据元素的集合 算法:处理数据的方式 编程风格: 面向对象:把所有的操作都转化为对象的方式. 面向过 ...