零碎记事

  距离上次发博客已经有一年半了,转眼间我也是从做图像研究到了做游戏开发,说起来看看前面的博文,本来就有前兆的东西呢(笑)......因为主要还是在使用虚幻引擎,所以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++封装静态链接库和使用的更多相关文章

  1. App开发流程之数据持久化和编译静态链接库

    先记录数据持久化. iOS客户端提供的常用数据持久化方案:NSUserDefaults代表的用户设置,NSKeydArchiver代表的归档,plist文件存储,SQLite数据库(包括上层使用的Co ...

  2. linux c静态链接库与动态链接库

    库函数是我们编程的时候经常用到的,我们协作编程的时候可以将常用的函数封装成库供大家使用,这样能够提高大家的工作效率.对于库函数,它分为动态链接库和静态链接库.对于静态链接库我们必须是连接到可执行文件中 ...

  3. dll和lib(包括静态链接库和与dll同时生成的lib)

    转:http://blog.csdn.net/galaxy_li/article/details/7411956 1:神马是Dll和Lib,神马是静态链接和动态链接 大家都懂的,DLL就是动态链接库, ...

  4. 静态链接库(lib)、动态链接库(dll)与动态链接库的导入库(lib)

    静态链接库与动态链接库相对应.动态链接库的导入库不同于以上两种库. 1.静态链接库(lib)     程序编译一般需经编辑.编译.连接.加载和运行几个步骤.在我们的应用中,有一些公共代码是需要反复使用 ...

  5. MFC 封装类为静态链接库

    mfc自带的基本控件都不怎么美观,所以一般开发者都会自定义类对控件进行重绘.手里也积累了不少控件的重绘,对对话框.静态文本.列表框等. 但是每次都要把这些类重新导入到新的工程里,比较麻烦,而且我也不想 ...

  6. vc下的静态链接库与动态链接库(一)

    一.静态库与动态库的区别 目前以lib后缀的库有两种,一种为静态链接库(Static Libary,以下简称“静态库”),另一种为动态连接库(DLL,以下简称“动态库”)的导入库(Import Lib ...

  7. C/C++ 静态链接库(.a) 与 动态链接库(.so)

    平时我们写程序都必须 include 很多头文件,因为可以避免重复造轮子,软件大厦可不是单靠一个人就能完成的.但是你是否知道引用的那些头文件中的函数是怎么被执行的呢?这就要牵扯到链接库了! 库有两种, ...

  8. VS2010编译Boost 1.57 静态链接库

    http://www.cnblogs.com/cuish/p/4175491.html 0.前提 Boost库版本 1.57.0 下载地址 http://www.boost.org/users/his ...

  9. 利用GCC编译器生成动态链接库和静态链接库

    转载请标明:http://www.cnblogs.com/winifred-tang94/ 1.编译过程 gcc –fPIC –c xxx.c 其中-fPIC是通知gcc编译器产生位置独立的目标代码. ...

随机推荐

  1. unity---光照基础

    发射光源类型 光照参数介绍 让摄像头看到Flare 耀斑 改变影子

  2. 安装Iftop到CentOS(YUM)

    iftop是Linux系统下实时流量监控工具. 运行环境 系统版本:CentOS Linux release 7.6.1810 (Core) 软件版本:Python 硬件要求:无 安装过程 1.安装i ...

  3. Vue关闭语法检测

    为什么?为了防止写到一半保存,报错.关闭默认的语法检测 新建vue.config.js 1.vue.config.js的作用是允许你修改脚手架中wekpack的默认参数. 2.vue.config.j ...

  4. 盘点微信小程序跨页面传值的若干方式

    直接给大家上干货 1.跳转页面传递参数 pageA.wxml <button type="primary" bindtap="jumpTo">点击跳 ...

  5. Nastran的应变方向

    问题 近日使用Nastran做一个算例,在计算频响时发现:位移场是连续的,而应变场不连续.以某一频率处应变场为例,其上表面X.Y方向应变场分布如下图.此处关闭了云图的插值,所显示的为单元的应变,因此云 ...

  6. 在CabloyJS中将Webpack生成的文件自动上传到阿里云OSS

    背景 阿里云OSS提供了一个Webpack插件,可在Webpack打包结束后将webpack生成的文件自动上传到阿里云OSS中 下面看看在CabloyJS中如何使用该插件 新建项目,并配置MySQL连 ...

  7. DYOJ 【20220317模拟赛】瞬间移动 题解

    瞬间移动 题意 三维空间中从 \((0,0,0)\) 开始,每次移动 1,问刚好走 \(N\) 次能到 \((X,Y,Z)\) 的方案数 \(N\le10^7\),答案模 \(998244353\) ...

  8. USB机械键盘改蓝牙键盘

    手里有两把机械键盘,一个是IKBC 87键,一个是IKBC POKER II 60键,由于买的比较早,两把键盘均为USB的,使用起来桌面线比较多,碍事,于是开始研究如何改成蓝牙键盘. 首先说一下USB ...

  9. python小题目练习(五)

    题目:Python实现快速排序 代码实现: """Author:mllContent:Python实现快速排序Date:2020-11-05""&qu ...

  10. idea中创建Java类时,自动在文件头中添加作者和创建时间

    在Settings中找到File and Code Templates 设置如下图所示. 效果展示: