零碎记事

  距离上次发博客已经有一年半了,转眼间我也是从做图像研究到了做游戏开发,说起来看看前面的博文,本来就有前兆的东西呢(笑)......因为主要还是在使用虚幻引擎,所以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. Spark框架——WordCount案例实现

    package wordcount import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} ...

  2. Spring-boot整合Activiti7

    Spring-boot整合Activiti7 pom.xml    <properties>        <maven.compiler.source>15</mave ...

  3. DML数据操作语言

    DML数据操作语言 用来对数据库中表的数据记录进行更新.(增删改) 插入insert -- insert into 表(列名1,列名2,列名3...) values (值1,值2,值3...):向表中 ...

  4. Unicode和中午互转

    import java.io.UnsupportedEncodingException; public class TestUnicode{ /* * 中文转unicode编码 */ public s ...

  5. Redis - Redlock算法

    Redis - Redlock算法 在Redis的分布式环境中,我们假设有N个Redis master.这些节点完全互相独立,不存在主从复制或者其他集群协调机制.之前我们已经描述了在Redis单实例下 ...

  6. Node.js amqplib 连接 Rabbitmq 学习笔记

    var amqp = require('amqplib'); connect([url, [socketOptions]]) var amqp = require('amqplib/callback_ ...

  7. 深入理解springboot的自动注入

    一.开篇   在平时的开发过程中用的最多的莫属springboot了,都知道springboot中有自动注入的功能,在面试过程中也会问到自动注入,你知道自动注入是怎么回事吗,springboot是如何 ...

  8. XSS攻击(笔记)

    XSS攻击 XSS概述 XSS即跨站脚本攻击,(Cross-Site Scripting, CSS),但是为了与层叠样式表(Cascading Style Sheets, CSS)缩写区分开来,所以命 ...

  9. 【python基础】第08回 流程控制 for循环

    本章内容概要 1.循环结构之 for 循环 本章内容详解 1.循环结构之for循环 1.1 语法结构 for 变量名 in 可迭代对象: #字符串 列表 字典 元组 for 循环的循环体代码 针对变量 ...

  10. java获取本地json格式的内容

    前言 该功能模块基于springBoot,自己在开发中遇到相关功能开发,总结如写: 1.首先将所需要获取的json文件放在项目resource目录下: 2.所需要的pom依赖: <depende ...