C++封装静态链接库和使用的详细步骤
作者:雾里尘埃 发布时间:2021-08-28 00:54:13
零碎记事
距离上次发博客已经有一年半了,转眼间我也是从做图像研究到了做游戏开发,说起来看看前面的博文,本来就有前兆的东西呢(笑)......因为主要还是在使用虚幻引擎,所以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")
现在讲怎么在项目里配置具体到指定库。
项目属性->链接器->输入->附加依赖项->编辑->添加你的库
设完就是不加编译头也能编译运行程序了,这是效果
来源:https://www.cnblogs.com/wulichenai/p/16563452.html


猜你喜欢
- 自然排序TreeSet集合在存储数据时有一定的顺序,它会将一些数据进行比较,比较调用的是comparaTo()方法,该方法是在Compara
- 概述现实生活中,我们常会看到这样的一种集合:IP地址与主机名,身份证号与个人,系统用户名与系统用户对象等,这种一一对应的关系,就叫做映射。J
- 1、SpringMVC验证@Validated的使用第一步:编写国际化消息资源文件编写国际化消息资源ValidatedMessage.pro
- spring Boot 使用事务非常简单,首先使用注解 @EnableTransactionManagement 开启事务支持后,然后在访问
- 前言代理模式,我们这里结合JAVA的静态代理和 * 来说明,类比Spring AOP面向切面编程:增强消息,也是代理模式。而我们的静态代理
- 简单工厂模式工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创
- 什么是Run Dashboard当springcloud的服务有多个时,管理多个服务的启动使用run会不好管理,这样我们就可以使用Run D
- —学习并使用mybatis-plus的一些高级功能的用法例如: AR模式、 乐观锁 、逻辑删除 、自动填充、数据保护等功能为了方便演示,咱们
- 常用:System:根空间,包含一些基本的类库 System.Collections:主要是和集合类相关的类库 System.Collect
- 本篇博客给大家分享一个效果比较好的侧滑菜单的Demo,实现点击左边菜单切换Fragment。效果如下: 主Activity代码:p
- 生产者工程POM依赖可以在创建工程时直接选择添加依赖。application文件因为rabbitmq具有默认地址及用户信息,所以如果是本地r
- 前言之前我们说10分钟学会Visual Studio将自己创建的类库打包到NuGet进行引用(net,net core,C#),过程有些许繁
- 1 自定义类加载器自定义类加载器的代码很简单,只需要继承ClassLoader类,覆写findClass方法即可其默认实现是会抛出一个异常:
- c#创建圆形类,其中包括set,get方法using System;using System.Collections.Generic;usi
- 笔者最近需要上位机与下位机进行数据交互,在广泛参考大佬的资料后,较为完善地使用Textbox控件进行数据输入的功能。程序段主要功能:实现输入
- 熟悉Android的朋友们都知道,不管是微博客户端还是新闻客户端,都离不开列表组件,可以说列表组件是Android数据展现方面最
- 之前学完了Java SE的知识,掌握了面向对象的编程思想,但对集合、多线程、反射、流的使用等内容理解的还不是很深入,打算再学习数据结构与算法
- Consumer消费者Demo示例<?xml version="1.0" encoding="UTF-8
- 实例如下所示:System.Net.WebClient myWebClient = new System.Net.WebClient();
- 本文实例为大家分享了Android实现背景图片轮播的具体代码,供大家参考,具体内容如下点击按钮实现图片轮播效果实践案例:xml<?xm