c++下程序的运行(第3方库的安装及安装gdal)

2023-05-16

C++安装第三方库

  • 1 概览
  • 2 编译,首先要熟悉程序编译过程(预处理->编译->汇编->链接)
    • 2.1 编译流程4步
      • 2.1.1 1 预处理
      • 2.1.2 2 编译
      • 2.1.3 3 汇编
      • 2.1.4 4 链接
    • 2.2 linux中c++程序的运行和windows中程序的运行
      • 2.2.1 Windows中c++程序的编译运行
      • 2.2.2 linux中c++程序的编译运行
    • 2.3 Debug模式和Release模式
    • 2.4 编译工具有哪些(不同系统下用不同的软件)
      • 2.4.1 哪些是编译工具
        • 1 GNU组织的G++(linux系统)
        • 2 Windows的Mingw/MSVC(专门针对Windows系统,两个软件不一样,用其一就行)
        • 3 LLVM的clang/clang++(针对于苹果IOS系统的编译软件)
        • 4 Make和CMake(CMake是在编译器基础上实现跨平台的软件,它会基于windows或linux选择正确的编译器,make是比g++高一层的工具,CMake是比Make更高一层的工具。)
        • 5 Windows和linux分别用什么编译工具
        • 6 编译到底需要什么东西,和编程软件无关
        • 7 makefile和Cmakelist
        • 8 需要学习的4个环境运行的基本知识
      • 2.4.2 GNU、GCC、G++
    • 2.5 集成工具(vs、vscode、clion)
    • 2.6 各种文件含义汇总
  • 3 第3方库的引用(只有两个阶段用,一是在编程时引入不报错;二是在打包成可执行文件时不报错打包出的程序正常执行。)
    • 3.1 需要解决的两个问题
    • 3.2 需要实现的几个功能(实现这几个功能就把第3方库环境和c++程序的执行彻底搞清楚了)
    • 3.3 第3方库涉及到的一些文件和概念
      • 3.3.1 头文件
      • 3.3.2 库文件(静态库和动态库用1种就行,不要都用,两者都是代码共享的方式)
        • 3.3.2.1 静态库
        • 3.3.2.2 动态库
        • 3.3.2.3 windows及linux环境下动态库和静态库的制作
      • 3.4.3 头文件和库文件的区别联系
      • 目标文件
      • 参考:
    • 3.4 第三方库是什么
      • 3.4.1 第三方库是什么
      • 3.4.2 第三方库怎么用(流程)
      • 3.4.3 引用第3方库的几个小案例
      • 3.4.4 lib库的配置有两种方式
      • 3.4.5 windows下引入第三方库
      • 3.4.6 linux下引入第3方库
      • 3.4.7 c++调用第3方库的管理工具vcpkg(类似python的pip,目前几乎没人用,了解一下)
    • 3.5 (1)准备数据,第三方库编译
    • 3.6 (2)配置环境:配置第三方库
    • 3.7 (3)编程时:添加头文件,引用第3方库
    • 3.8 (4)编译时:打包带第3方库的程序
    • 3.9 (5)执行程序时
  • 4 不同软件下使用第3方库
    • 4.1 windows系统下导入第3方库
      • 4.1.1 VS中第三方库安装流程
      • 4.1.2 Clion中第三方库安装流程
      • 4.1.3 vscode中第三方库安装流程
      • 4.1.4 CmakeList
        • 4.1.4.1 Cmakelist添加动态库
        • 4.1.4.1 Cmakelist添加静态库
    • 4.2 linux系统下导入第3方库
      • 4.2.1 CmakeList
      • 4.2.2 makefile
  • 5 安装gdal库
    • 5.1 Clion安装GDAL库
      • 5.1 成功安装
      • 5.1.2 核心要点
    • 5.2 VS软件环境安装gdal库
      • 5.2.1 使用配置好的环境读取栅格信息(已成功执行)
      • 5.2.2 使用配置好的环境读取shp文件(已成功执行)
    • 5.3 linux环境下安装gdal库
    • 5.4 尝试实现的几个教程案例
  • 6 安装Opencv库
    • 6.1 vs2019安装opencv库
  • 总结
  • 参考文献

1 概览

安装第3方库无非就是4步:
(1)编译第三方库源码;
(2)在开发工具中进行配置,这样才能引用;
(3)代码中引用编程;
(4)打包成可执行文件。

需要理清楚的就3个问题:
(1)第三库的形式有哪些,在linux和windows中的形式?
(2)不同开发工具如何配置第三方库?
(3)编译和打包工具怎么使用?

学习编程就是先学习:
(1)编程语言;
(2)各种工具(集成工具vs,发布工具git,数据库工具mysql等等);
(3)各种第3方库,也可以算作工具,别人写好的一些功能。
(4)解决实际问题;

2 编译,首先要熟悉程序编译过程(预处理->编译->汇编->链接)

2.1 编译流程4步

参考文档:
Windows下使用MinGW在命令行编译运行C++程序案例实操

2.1.1 1 预处理

预处理主要处理源文件中的“#include”、“#define”等预处理命令
预处理主要完成的工作有:
(1)删除#define,展开宏;
(2)处理条件编译指令,预处理程序先判断条件,在根据条件修改源代码;
(3)删除注释;
(4)添加行号,以及文件名标识,便于调试
(5)删除“#include”,插入相应的头文件;
使用g++ -E test.cpp -o test.i命令,预处理后得到test.i文件

在这里插入图片描述

2.1.2 2 编译

生成汇编代码的过程,使用命令g++ -S test.i -o test.s生成汇编文件test.s文件,当然直接从test.cpp文件得到汇编文件也可以。
在这里插入图片描述

2.1.3 3 汇编

将汇编代码转化成机器指令,生成目标二进制代码。
使用命令g++ -c test.s -o test.o 生成test.o文件

2.1.4 4 链接

通过链接库文件,将目标文件转化成可执行文件
使用命令g++ test.o -o test.exe -L 所需库文件路径 其中L为link的缩写
在这里插入图片描述

当然,一般情况下,可以直接使用g++ test.cpp -o test 就可以生成可执行程序了,不用上面一步一步操作。

2.2 linux中c++程序的运行和windows中程序的运行

2.2.1 Windows中c++程序的编译运行

和2.1节一样,编译的4步,可以直接使用g++ test.cpp -o test 就可以生成可执行程序了。

Windows下使用MinGW在命令行编译运行C++程序案例实操

2.2.2 linux中c++程序的编译运行

Linux平台开发运行C++程序大体流程与Windows下差别不大
1.编写.cpp文件,C++代码都在里面;
2.可能还有一些.h文件之类的支持文件,这些文件一般都会放在一起,或者相对位置是固定的;
3.编译文件,生成可执行文件,在Windows中为.exe,Linux下是.out文件;
4.运行可执行文件,Linux下通过命令运行可执行文件;

要想让编好的代码在Linux上运行,我们需要使用GCC
预编译:将hello.c和stdio.h预编译为hello.i
编译:将hello.i编译为hello.s,这是汇编文件。
汇编:将hello.s翻译为机器指令hello.o(.o目标文件)
链接:链接各种需要的库和其他目标文件(该hello程序不需要)得到可执行文件hello.out(相当于windows的.exe)

linux平台编译运行c++程序_linux编译cpp文件案例实操_Menglon的博客-CSDN博客

2.3 Debug模式和Release模式

debug的意思是“排除错误,调试”,release是“释放,释放”;

Debug文件夹:调试–调试完成成功生成可执行程序,失败返回失败数据
Release文件夹:发布版本–发布需要发布的可执行程序

Debug 版本
Debug 是“调试”的意思,Debug 版本就是为调试而生的,编译器在生成 Debug 版本的程序时会加入调试辅助信息,并且很少会进行优化,程序还是“原汁原味”的。

你没听错,不是任何一个程序都可以调试的,程序中必须包含额外的辅助信息才能调试,否则调试器也无从下手。
Release 版本
Release 是“发行”的意思,Release 版本就是最终交给用户的程序,编译器会使尽浑身解数对它进行优化,以提高执行效率,虽然最终的运行结果仍然是我们期望的,但底层的执行流程可能已经改变了。

编译器还会尽量降低 Release 版本的体积,把没用的数据一律剔除,包括调试信息。

最终,Release 版本是一个小巧精悍、非常纯粹、为用户而生的程序。

在这里插入图片描述

2.4 编译工具有哪些(不同系统下用不同的软件)

首先是如雷贯耳的这几位仁兄,MSVC、GCC、Cygwin、MingW(Cygwin和MingW的英文发音),另外还有些小众和新秀,像ICC(Intel C/C++ Compiler)、BCC(Borland C/C++ Compiler,快销声匿迹了)、RVCT(ARM的汇编/C/C++编译器,内置在ARM的IDE——RVDS中)、Pgi编译器……其实有一大串,我们只要熟悉常用的最强大的几款就可以了。

lx必看,这个文档太好了,太好了,捋一捋gcc/g++/MingW/MSVC与make/CMake的关系 - 知乎
比较好用的c++编译器(好用的C++编译器)

2.4.1 哪些是编译工具

1 GNU组织的G++(linux系统)

GCC/G++,可以认为它们是一样的,在windows和linux系统下都可以用g++进行编译。

在Linux虚拟机上安装gcc/g++_linux安装g++_WW

2 Windows的Mingw/MSVC(专门针对Windows系统,两个软件不一样,用其一就行)

MinGW(Minimalist GNUfor Windows),它是一个可自由使用和自由发布的Windows特定头文件和使用GNU工具集导入库的集合,允许你在Windows平台生成本地的Windows程序而不需要第三方C运行时(C Runtime)库。

用MinGW的时候实际上也是运行一些g++命令,因为MinGW集成了一下GNU组织的g++工具。

用Clion等软件时也需要配置好MinGW或者MSVC;

运行时库:支持程序运行的基本函数的集合,一般是静态库lib或动态库dll。

而MSVC,就是上文所说的第三方C运行时库:由微软开发的VC运行时库,被Visual Studio IDE所集成。所以我们使用VS时会附带MSVC编译器。

所以可以看到啦,MinGW和MSVC都是Windows C/C++语言编译支持,配置环境时遇到两者择其一即可。

下载安装MinGW-w64详细步骤(c/c++的编译器gcc的windows版,win10真实可用)_jjxcsdn的博客-CSDN博客

3 LLVM的clang/clang++(针对于苹果IOS系统的编译软件)

有了前文,对LLVM与clang不用解释应该也知道了。

LLVM是构架编译器(compiler)的框架系统,以C++编写而成,用于优化以任意程序语言编写的程序的编译时间(compile-time)、链接时间(link-time)、运行时间(run-time)以及空闲时间(idle-time),对开发者保持开放,并兼容已有脚本。

LLVM计划启动于2000年,最初由美国UIUC大学的Chris Lattner博士主持开展。2006年Chris Lattner加盟Apple Inc.并致力于LLVM在Apple开发体系中的应用。Apple也是LLVM计划的主要资助者。

目前LLVM已经被苹果IOS开发工具、Xilinx Vivado、Facebook、Google等各大公司采用。

4 Make和CMake(CMake是在编译器基础上实现跨平台的软件,它会基于windows或linux选择正确的编译器,make是比g++高一层的工具,CMake是比Make更高一层的工具。)

有了编译器GCC等等, 为什么要有make这个构建生成器,同样是老生常谈的内容。

编译hello.c非常简单,只需要

$ gcc hello.c

就可以了,但当项目庞大起来后,假设hello.c依赖与a.c、b.c,而a.c又依赖于库w.lib,每一次编译,我们都要重新编写一次gcc编译命令行吗?

所以,GNU发明了make这个工具软件,可以编写makefile文件来指定特定的项目构建过程,当项目一个文件的代码更改时,我们只需要重新make一下就可以了。

make工具可以看成是一个智能的批处理工具,它本身并没有编译和链接的功能。

但make依然有很多不足,比如

make对于类unix系统是通用的,但对windows系统并不友好(不能跨平台),当然windows系统中也可以安装make,但是在windows下创建的makefile无法在linux上用。

make语法简单,也就导致了它功能的限制
不同编译器的语法规则不同,编写的makefile语法如果适合GCC则不适合MSVC
所以,CMake就应运而生啦。

CMake是比Make更高一层的工具,Make是编写对应编译器的makefile从而实现编译,而CMake是写一份独立的CmakeList.txt文件,然后该文件会根据当前系统环境选择适合的构建生成器(如VS或者make),然后将CmakeList.txt翻译为适合的文件,再进一步调用系统编译器进行项目构建。

总结:
(1)make软件的作用只有1个:
解决项目依赖很多第3方库时,g++功能不足的问题,是在g++基础上的一个软件,用于把依赖库给理清楚,然后调用g++工具进行编译,弥补g++的缺陷,实现维护第3方库的功能
(2)Cmake软件的作用只有1个:
弥补make不能跨平台的缺陷,实现跨平台维护第3方库的2个功能。
(3)二者区别:
区别1:make软件只能用于linux系统,也有的说可以用于windows,但是不能通用1个makefile文件,Cmake软件可以跨平台使用;
区别2:make软件编写makefile文件实现编译;Cmake编写执行CmakeList.txt实现编译。

lx必看,这个文档太好了,太好了,捋一捋gcc/g++/MingW/MSVC与make/CMake的关系 - 知乎

lx必看, Makefile和Cmake的区别和联系_cmake和makefile区别_这个文档里的Cmake介绍有一个错误,它也支持windows,不仅仅是linux

windows平台下makefile操作教程_windows makefile_帅德布耀德的博客-CSDN博客

从零开始详细介绍CMake_哔哩哔哩_bilibili

【cmake教程】为你的项目引入外部第三方库(以真实项目partio为例)_哔哩哔哩_bilibili

5 Windows和linux分别用什么编译工具

(1)Windows下就用的Mingw或者MSVC,会Cmake;
(2)linux下就用g++,make,Cmake

6 编译到底需要什么东西,和编程软件无关

(1)当我们编译一个程序的时候,用到的是g++编译软件或者Mingw软件,而不是vs、vscode、clion这些软件。
(2)我们编写程序的时候无非是用txt就行,编译软件的时候直接用Mingw软件,这样就可以得到可执行文件了。
(3)vs、vscode、clion的作用就是把记事本(或其它文本编辑器)、编译软件Mingw给集成在一起了,它就是一个集成的工具。你在vs、vscode、clion里面可以更换编译软件Mingw或者MSVC。

7 makefile和Cmakelist

看上面第4节讲的,它们都是文件,分别用于make软件和Cmake软件处理。

(1)Makefile
Makefile 文件描述了 Linux 系统下 C/C++ 工程的编译规则,它用来自动化编译 C/C++ 项目。一旦写编写好 Makefile 文件,只需要一个 make 命令,整个工程就开始自动编译,不再需要手动执行 GCC 命令。
(2)Cmakelists
CMake通过CMakeLists.txt配置项目的构建系统,配合使用cmake命令行工具生成构建系统并执行编译、测试,相比于手动编写构建系统(如Makefile)要高效许多。对于C/C++项目开发,非常值得学习掌握。

Makefile教程:Makefile文件编写1天入门

CMakeLists教程(实战总结)_开酒不喝车的博客-CSDN博客
CMake应用:CMakeLists.txt完全指南 - 知乎

8 需要学习的4个环境运行的基本知识

(1)makefile的写法

[1] 王道训练营的视频课
[2]makefile 完美教程_makefile教程_WittXie的博客-CSDN博客
[3] Makefile基础教程_makefile菜鸟教程-C文档类资源-CSDN文库

(2)Cmakelist的写法;

看第4章的Cmakelist导入第三方库,里面有很多教程。

(3)编程中不同系统不同软件如何引用第3方库进行编程;

1 Windows+记事本:
2 Windows+VS:
3 Windows+vscode:
4 Windows+Clion:
5 Linux+VIM:
6 Linux+Clion:
7 Linux+vscode:

(4)编程中不同系统不同软件如何打包含第3方库的代码生成可执行文件;

2.4.2 GNU、GCC、G++

GNU是一个开放组织,GCC/G++是它的产品。
GCC就是g++;
首先我们可以将GCC/G++看成一个整体,不存在GCC专门编译C语言,G++专门编译C++语言这种分别,因为编程语言发展至今是非常复杂的,编译器同样也是。我们将两者都看成GCC,GCC支持C、C++和Fortran语言。

而GCC(GNU Compiler Collection,GNU编译器集合),就是GNU运动的代表性成果,它的初衷是为GNU的自由系统开发完整的编译器。

所以,在Linux甚至Windows上各种涉及开发环境配置,源码编译的地方,都离不开gcc和g++。

lx必看,这个文档太好了,太好了,捋一捋gcc/g++/MingW/MSVC与make/CMake的关系 - 知乎

2.5 集成工具(vs、vscode、clion)

集成工具就是把编码工具、编译工具、debug调试工具等结合在一起的一个软件,不要想的多牛逼。

集成工具在你写代码的时候会给一些提示,方便一些;
编译工具等都可以在集成工具中进行调试。
还可以打断点,进行代码调试。

但是平时使用Visual Studio等软件时并没有接触到编译这个过程,因为VS是高度集成开发环境(IDE、Integrated Development Environment),集成了代码编辑器,编译器,调试器和图像化用户界面,上述所有程序编译和链接过程都用一步build构建带过了。

我们学习编程在集成工具上进行,除了编程语言本身语法特点外,还要了解集成工具的使用,使用集成工具来编辑代码实现特定功能,解决实际问题。

重要的话说3遍:
在编程时不用集成工具也行,只要给个记事本或者vim都可以进行编程的,但是集成工具更方便些!
在编程时不用集成工具也行,只要给个记事本或者vim都可以进行编程的,但是集成工具更方便些!
在编程时不用集成工具也行,只要给个记事本或者vim都可以进行编程的,但是集成工具更方便些!

VS(Visual Studio)工具介绍

2.6 各种文件含义汇总

(1)编译过程的文件:
.i 高级语言进行编译4步中第1步预处理后得到的文件;
.s 汇编文件test.s,由高级语言编译得到,下一步是通过这个文件汇编成.o机器指令文件;
.o 机器指令文件,也叫目标二进制代码文件;
.out linux系统下的可执行文件,和windows下的.exe文件一样
.exe windows下的可执行文件;

(2)第三方库文件:
.h 头文件:用于声明第3方库类、函数;
makefile文件:用于make软件中编译c++程序源文件;
CmakeLists文件:用于Cmake软件编译c++程序源文件;

windows和linux中的静态库和动态库,具体区别见下面第3章的库文件介绍:
(2.1)Windows中:
.lib: Windows中生成c++的静态库,Windows中生成静态库的工程,编译生成成功后,只产生一个.lib文件。
.dll和.lib: Windows中c++的动态库,Windows中生成动态库的工程,编译成功后,产生一个.lib文件和一个.dll文件。

(2.2)linux中:
.a文件: c++语言在linux系统中的静态库,c++静态库在linux中是以.a(archive)为后缀,作用是在进行链接生成可执行文件时,从静态库文件中拷贝需要的内容到最终的可执行文件中。
.so文件:c++语言在linux系统中的动态库,动态库在linux中是以.so(shared object)为后缀,它并不在链接时将需要的二进制代码都拷贝到可执行文件中,而是拷贝一些重定位和符号表信息,当程序运行时需要的时候再通过符号表从动态库中获取。

3 第3方库的引用(只有两个阶段用,一是在编程时引入不报错;二是在打包成可执行文件时不报错打包出的程序正常执行。)

3.1 需要解决的两个问题

(1)在编辑的时候如何引用第3方库;
(2)打包生产可执行程序的时候如何用第三方库。

3.2 需要实现的几个功能(实现这几个功能就把第3方库环境和c++程序的执行彻底搞清楚了)

(1)在记事本上写读取文件并输出的功能,并编译成可执行文件,不用vs、vscode、clion。
(2)在记事本上调用第3方库,opencv写读取图像并改变大小保存的功能,并编译成可执行文件。
(3)在Clion和VS上或vscode调用第3方库,opencv写读取图像并改变大小保存的功能,并编译成可执行文件。(熟练软件应用)
(4)在linux系统中实现上面3个同样的功能。

3.3 第3方库涉及到的一些文件和概念

3.3.1 头文件

头文件是包含函数声明,宏定义,类的声明的文件,里面就是一些声明(声明了之后这样你的.cpp文件才能用这些函数、类)。

在linux中一般头文件会在/usr/include中,如果没有可以使用 locate命令查找文件所在位置。

(1)为什么只用在程序头部写上包含的头文件,头文件中并没有实现内容就可以使用声明的函数呢?

因为头文件和库文件相关联。

首先要熟悉程序编译过程:预处理->编译->汇编->链接;
在这里插入图片描述

3.3.2 库文件(静态库和动态库用1种就行,不要都用,两者都是代码共享的方式)

库文件是一种目标文件,静态库是可重定位目标文件,动态库是共享目标文件。
我们在实际用的时候用1种就行了,比如opencv库,可以有动态库和静态库,我们用其中一个就行,不要都用。

linux中的库文件一般在/usr/lib、/usr/lib64、/lib、/lib64都包含库文件

(1)库文件分为动态库和静态库:
**静态库:**在链接步骤中,连接器将从库文件取得所需的代码,复制到生成的可执行文件中,这种库称为静态库,其特点是可执行文件中包含了库代码的一份完整拷贝;缺点就是被多次使用就会有多份冗余拷贝。即静态库中的指令都全部被直接包含在最终生成的 EXE 文件中了。在vs中新建生成静态库的工程,编译生成成功后,只产生一个.lib文件。
**动态库:**动态链接库是一个包含可由多个程序同时使用的代码和数据的库,DLL不是可执行文件。动态链接提供了一种方法,使进程可以调用不属于其可执行代码的函数。函数的可执行代码位于一个 DLL 中,该 DLL 包含一个或多个已被编译、链接并与使用它们的进程分开存储的函数。在vs中新建生成动态库的工程,编译成功后,产生一个.lib文件和一个.dll文件。

(2)那么上述静态库和动态库中的lib有什么区别呢?
静态库中的lib:该LIB包含函数代码本身(即包括函数的索引,也包括实现),在编译时直接将代码加入程序当中
动态库中的lib:该LIB包含了函数所在的DLL文件和文件中函数位置的信息(索引),函数实现代码由运行时加载在进程空间中的DLL提供
总之,lib是编译时用到的,dll是运行时用到的。如果要完成源代码的编译,只需要lib;如果要使动态链接的程序运行起来,只需要dll。

(3)在linux和windows当中,静态库和动态库的区别:
在这里插入图片描述

lx非常好,非常好:动态库与静态库的区别、在windows及linux环境下的制作及用法_windows linux 动态库

(4)动静态库区别

1.可执行文件大小不一样
静态链接的可执行文件要比动态链接的可执行文件大得多,因为它将需要用到的代码从二进制文件中拷贝了一份,而动态链接仅仅是复制了一些重定位和符号表信息。

2.占用磁盘大小不一样
如果有多个可执行文件,那么静态库中的同一个函数的代码就会被复制多次,而动态库只有一份,因此使用静态库占用的磁盘空间相对比动态库要大。

3.拓展性与兼容性不一样
如果静态库中某个函数的实现变了,那么可执行文件必须重新编译,而对于动态链接生成的可执行文件,只需要更新动态库本身即可,不需要重新编译可执行文件。正因如此,使用动态库的程序方便升级和部署。

4.依赖不一样
静态连接的可执行文件不需要依赖其他的内容即可运行,而动态链接的可执行文件必须依赖动态库的存在。所以如果你在安装一些软件的时候,提示某个动态库不存在的时候也就不奇怪了。

即便如此,系统中一般存在一些大量公用的库,所以使用动态库并不会有什么问题。

5.复杂性不一样
相对来说,动态库的处理要比静态库要复杂,例如如何在运行时确认地址?多个进程如何共享一个动态库?当然,作为调用者我们不需要关注,另外动态库版本的管理也是一项技术活。这也不在本文的讨论范围。

6.加载速度不一样
由于静态库在链接时就和可执行文件在一块了,而动态库在加载或者运行时才链接,因此,对于同样的程序,静态链接的要比动态链接加载更快。所以选择静态库还是动态库是空间和时间的考量。但是通常来说,牺牲这点性能来换取程序在空间上的节省和部署的灵活性是值得的。再加上局部性原理,牺牲的性能并不多。(局部性原理是指CPU访问存储器时,无论是存取指令还是存取数据,所访问的存储单元都趋于聚集在一个较小的连续区域中。)

3.3.2.1 静态库

静态库在linux中是以.a(archive)为后缀,作用是在进行链接生成可执行文件时,从静态库文件中拷贝需要的内容到最终的可执行文件中。

//在使用gcc编译时采用 -static选项来进行静态文件的链接:
gcc -c main.c
gcc -static -o main main.o

linux系统中静态库的生产:

//1.先写出相应的.h文件和对应的.c文件
//2.编译.c文件
//3.使用ar工具将.o文件归档生成.a静态库文件
[root@localhost linux]# ls
add.c add.h main.c sub.c sub.h
[root@localhost linux]# gcc -c add.c -o add.o
[root@localhost linux]# gcc -c sub.c -o sub.o
生成静态库
[root@localhost linux]# ar -rc libmymath.a add.o sub.o
ar是gnu归档工具,rc表示(replace and create)
查看静态库中的目录列表
[root@localhost linux]# ar -tv libmymath.a
rw-r–r-- 0/0 1240 Sep 15 16:53 2017 add.o
rw-r–r-- 0/0 1240 Sep 15 16:53 2017 sub.o
t:列出静态库中的文件
v:verbose 详细信息
[root@localhost linux]# gcc main.c -L. -lmymath
-L 指定库路径
-l 指定库名
测试目标文件生成后,静态库删掉,程序照样可以运行。

注意:静态库文件和动态库文件的命名规则是libxxxx.a/libxxxx.so,在进行链接时只用lxxxx即可,不用写libxxxx.so。

在这里插入图片描述

3.3.2.2 动态库

动态库在linux中是以.so(shared object)为后缀,它并不在链接时将需要的二进制代码都拷贝到可执行文件中,而是拷贝一些重定位和符号表信息,当程序运行时需要的时候再通过符号表从动态库中获取。

//使用gcc编译默认采用动态链接
gcc -o main main.c

在这里插入图片描述

3.3.2.3 windows及linux环境下动态库和静态库的制作

lx非常好,非常好:动态库与静态库的区别、在windows及linux环境下的制作及用法_windows linux 动态库

3.4.3 头文件和库文件的区别联系

头文件是进行类、函数的声明;
库文件是存放类、函数的代码。
在这里插入图片描述
在这里插入图片描述

lx非常好非常好:如何生成动态库和静态库,lib 和 dll 的区别、生成以及使用详解
lx非常好,非常好:动态库与静态库的区别、在windows及linux环境下的制作及用法_windows linux 动态库

目标文件

在解释静态库和动态库之前,需要简单了解一下什么是目标文件。目标文件常常按照特定格式来组织,在linux下,它是ELF格式(Executable Linkable Format,可执行可链接格式),而在windows下是PE(Portable Executable,可移植可执行)。

而通常目标文件有三种形式:

(1)可执行目标文件。即我们通常所认识的,可直接运行的二进制文件。

(2)可重定位目标文件。包含了二进制的代码和数据,可以与其他可重定位目标文件合并,并创建一个可执行目标文件。

(3)共享目标文件。它是一种在加载或者运行时进行链接的特殊可重定位目标文件。

使用readelf -a filename 可以查看目标文件的ELF格式

参考:

lx非常好非常好,头文件和库文件区别,动态库和静态库的区别,动静态库的生成_头文件和库文件的区别
lx非常好,非常好:动态库与静态库的区别、在windows及linux环境下的制作及用法_windows linux 动态库

3.4 第三方库是什么

3.4.1 第三方库是什么

第三方库这个说法,不知道出自哪里,但一般是指开发者,系统/平台提供商之外的第三个参与者提供的程序库。大多数开源软件库在软件系统中都是第三方库。
完全不使用库的开发,在90年代就已经被放弃了,开源运动的兴起使得第三方库成为主力使用库。
C++领域有一些非常特殊的库,比如早期的STLport和当前的Boost,它们就像是语言的事实标准,基本在每个程序中都可以见到他们的身影。
一、引入第三方库就是引入动态库或静态库,引入源码也可以(但是一般不用源码,会把源码编译成动态库或者静态库)
二、使用第3方库可以让我们免去自己造轮子的过程,直接用别人造好的工具,大大提高开发效率和简化开发难度。
三、但第三方库也会导致相当多的问题,主要总是包括:
(1)版本不一致。同一个软件系统中,如果引用了同一个第三方库的两个不同版本,那一定会暗生问题。
(2)编译选项不一致。一般为了减少编译时间,第三方库都会以编译后的.a/.lib形式参与软件编译,第三方库的编译选项与软件系统的编译选项不同,也是会有一些潜在的问题。特别是x86/x64,ansi/utf-8这些选项不同,根本就不能用。
(3)版本管理库变大。在一些大项目中常常会有几个G的版本库,每次clone代价很大。其实很多都是第三方库,不同版本,不同编译选项生成的库引入。

四、第三方库升级问题:
另一方面,如果第三方库升级,就是一个比较复杂的工程,如果不升级,又只能看着第三方库的问题得不到解决。
在Linux上这个问题并不严重,系统级的软件管理工具可以代管大多数的第三方。比如debian系的,可以使用apt得到大多数的开源库,同时如果需要最新版本,也可以通过第三方源来取得。

在交叉编译和window平台上这个问题就非常头痛了。我们需要从几个层次来解决这个问题。

需要有中心化的第三方源代码获取平台,这个平台需要支持按用户/组织+第三方库+版本的形式取得源代码,同时还需要保证及时跟踪来源。这个类似于bintray/github都可以。公司内部可以使用gitlab来搭建。
需要有一个构建脚本平台,存放在不同工具链和平台的情况下,这个脚本可以从源代码中心的源代码,把源代码编译成库。同样可以用github这类工具搭建和管理。
在项目中提供一个配置文件,需要的开源库(只需指定编译脚本,脚本是针对开源库)。这个只需要一个文本文件即可。
在开发者的机器和编译服务器上,下载编译脚本,生成库。源代码、最终结果可以缓存在本机上。可以使用项目原本的构建工具。

3.4.2 第三方库怎么用(流程)

除了把编译的库引入项目,也有人以源代码的形式引入开源软件,比如GCC、SDL、WxWights、QT。如果第三方库本身编译不复杂,原代码也很简单,这么做比较好。
但是像Boost.Thread这样的库,就不行了。它需要编译成动态库,静态引用会有问题。

第3方库的引入方式一共有3种:
(1)源码: 在工程中需包含引用工程的源文件(.cpp)和头文件(.h),这种方法会导致工程较为庞大,引用2个东西。
(2)动态库: 只需包含引用工程的dll文件即可,引用工程的头文件和lib库文件可选,通常都会带上。引用3个东西。
(3)静态库: 只需包含引用工程编译生成的lib文件和头文件,工程看起来较为清爽简洁,引用2个东西。

(1)准备数据:对第三方库的源码进行编译成动态库或者静态库(我们可以找到编译好的动态库或静态库,这样避免自己编译出错)。
(2)配置环境:配置到你的项目中,可以是vs、clion、记事本,为你的项目导入该a文件或者lib文件和头文件。
(3)编程:引用头文件,并调用第三方库函数编程:进行编程。
(4)编译:打包成可执行程序:Cmake打包编译,或者g++编译。
(5)运行:运行可执行程序:如果是动态库的话,需要将.dll文件或者.so文件放到.exe或.out的同级目录,静态库的话不用。。

在这里插入图片描述

lx非常好非常好 C++中第三方库的一般使用方式(libxl库为例)

3.4.3 引用第3方库的几个小案例

具体案例可以看第4章的描述
案例一:
使用第三方库的方法(假定库名为FOO):
(1)准备数据:编译源码:编译FOO的cpp文件(连同需要的h文件)一起编译为o文件。将o文件打包为a文件或者lib文件。
(2)配置环境:配置到你的项目中,可以是vs、clion、记事本,为你的项目导入该a文件或者lib文件和头文件。
(3)编程:引用头文件,并调用第三方库函数编程:进行编程。
(4)编译:打包成可执行程序:Cmake打包编译,或者g++编译。
(5)运行:运行可执行程序:如果是动态库的话,需要将.dll文件或者.so文件放到.exe或.out的同级目录。
案例二:
lx非常好非常好 C++中第三方库的一般使用方式(libxl库为例)

3.4.4 lib库的配置有两种方式

一种是在代码中进行配置
一种是Cmakelist或者vs等软件按钮中进行配置;

3.4.5 windows下引入第三方库

首先明确一点,windows下引入第三方库就是引入动态库或者静态库,源码也行,但是一般不用源码。
(1)windows中使用静态库的方法导入第3方库,就是配置好.h头文件和.lib文件这两个文件。
(2)windows中使用静态库的方法导入第3方库,就是配置好头文件和.lib文件这两个文件,在静态库的基础上再把.dll动态库文件放到.exe同级目录(debug和release模式下exe在不同文件夹)。
(3)windows引入第3方库两种方式:一是使用Cmakelist文件组织、类似于maven;二是在vs、clion等软件中直接配置。

3.4.6 linux下引入第3方库

首先明确一点,linux下引入第三方库就是引入动态库或者静态库。
(1)linux中使用静态库的方法导入第3方库,就是配置好.h头文件和.a文件这两个文件。
(2)linux中使用动态库的方法导入第3方库,就是配置好.h头文件和.a文件这两个文件,在静态库的基础上再把.so动态库文件放到.out同级目录。
(3)linux中引入第3方库的两种方式:一是使用makefile文件;二是使用Cmakelist文件组织。

3.4.7 c++调用第3方库的管理工具vcpkg(类似python的pip,目前几乎没人用,了解一下)

包管理器就是一个用来管理这些库的!!!你想用谁的库,就用谁的库!!!vcpkg是一个C++的包管理器,各语言的包管理都已经做的很NB,C++才开始起步。

还在手动编译第三方库?vcpkg来帮你解决,完美的C++包管理器!!速速食用!!哔哩哔哩_bilibili
C++第三方库管理工具vcpkg使用教程_令狐掌门的博客-CSDN博客

3.5 (1)准备数据,第三方库编译

就是制作静态库或动态库。

3.6 (2)配置环境:配置第三方库

windows和linux平台C++工程 如何连接第三方依赖库_libopencv_world.so.4.5_于工不移山的博客-CSDN博客

3.7 (3)编程时:添加头文件,引用第3方库

Windows中C++动态库和静态库的使用方法和区别_使用静态库需要头文件吗_QuattroA8的博客-CSDN博客

3.8 (4)编译时:打包带第3方库的程序

3.9 (5)执行程序时

如果用的是动态库,需要将所有的dll或者so文件copy到exe文件所在目录下,注意:运行时的工作目录不在这个文件下也是会出错的,如/root//*.exe ,会报找不到.so文件或者dll文件。
windows就用.dll文件就可以了;
linux系统中就用.so文件。

4 不同软件下使用第3方库

4.1 windows系统下导入第3方库

4.1.1 VS中第三方库安装流程

一共4步:
1 添加头文件目录include
2 添加静态库目录lib库
3 添加附加依赖项,也就是具体的静态库文件
4 将动态库文件放到.exe的同级目录下

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

但是平时使用Visual Studio等软件时并没有接触到编译这个过程,因为VS是高度集成开发环境(IDE、Integrated Development Environment),集成了代码编辑器,编译器,调试器和图像化用户界面,上述所有程序编译和链接过程都用一步build构建带过了。

[1] lx非常好非常好 如何调用动态库和静态库 lib 和 dll 的区别、生成以及使用详解
[2] lx非常好非常好 C++中第三方库的一般使用方式(libxl库为例)
[3] C++基础-如何引入第三方静态库、动态库或自定义库_c++如何导入第三方库
[4] C++第三方日志库Glog的安装与使用介绍

4.1.2 Clion中第三方库安装流程

[1] CLion中使用CMake导入第三方库的方法_clion中引入第三方库的详细方法

下面这个写的很清楚,要先将源码编译成动态库或者静态库再导入
[2] CLion中C++加载静态库和动态库-CSDN博客

[3] lx非常好非常好CMakeLists.txt 语法简明教程CSDN博客

4.1.3 vscode中第三方库安装流程

vscode调用第三方库好像要配置json文件。
VScode中使用C++语言调用第三方库的方法 - 知乎

4.1.4 CmakeList

CmakeList.txt是Cmake软件执行的一个文件,通过CmakeList可以直接引入第3方库,添加第3方库主要就是3个命令:
1 是添加.h头文件;
2 是添加库文件;
3 是添加动态库(添加的是动态库的话)

#设置cmake版本
cmake_minimum_required(VERSION 3.22)
#项目名字
project(first)
#设置编译版本
set(CMAKE_CXX_STANDARD 14)
#引入头文件
include_directories(D:\\XiaoMaCode\\CPlusPlusCode\\Third_party_library\\gdal\\include)
#引入库文件
link_directories(D:\\XiaoMaCode\\CPlusPlusCode\\Third_party_library\\gdal\\lib)
#编译文件,这个不知道应该放在最后还是放在这里
add_executable(first main.cpp)
#将第三方库连接在一起
target_link_libraries(first libgdal.a)

target_link_libraries需要放在add_executable之后,用于指明连接进来的库,官方推荐使用这个接口,而不推荐使用link_libraries,link_libraries需要放到add_executable之前。

lx非常好非常好CMakeLists.txt 语法简明教程CSDN博客

CMakeLists.txt的超傻瓜手把手教程(附实例源码)_Yngz_Miao-DevPress官方社区

cmake 添加头文件目录,链接动态、静态库-CSDN博客

从零开始详细介绍CMake_哔哩哔哩_bilibili

CLion中使用CMake导入第三方库的方法_clion中引入第三方库的详细方法

CMake 引入第三方库_cmake添加第三方库_ccsu_zzh的博客-CSDN博客

cmake 引入第三方库(头文件目录、库目录、库文件)_cmakelist 添加第三方库_仲夏夜之梦~的博客-CSDN博客

CMake 引入第三方库_cmake添加第三方库_ccsu_zzh的博客-CSDN博客

4.1.4.1 Cmakelist添加动态库

# CMakeList.txt: QT_CMake 的 CMake 项目,在此处包括源代码并定义

cmake_minimum_required (VERSION 3.20.1)

project (QT_CMake  CXX)

# 添加c++ 17标准支持
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 寻找OpenCV库
set(OpenCV_DIR "D:/vcpkg/vcpkg/packages/opencv4_x64-windows")
find_package(OpenCV REQUIRED)
# GDAL库路径、GDAL_INCLUDE头文件、GDAL_LIBRARY库文件
set(GDAL_DIR "D:/gdal_tool/release-1928-x64-dev/release-1928-x64")
file(GLOB_RECURSE GDAL_LIBRARY "${GDAL_DIR}/lib/*.lib")
file(GLOB_RECURSE GDAL_INCLUDE "${GDAL_DIR}/include/*.h")


# 设置OpenCV与GDAL头文件的目录
include_directories(${OpenCV_INCLUDE_DIRS})
set(GDAL_INCLUDE_DIRS "${GDAL_DIR}/include" "${GDAL_DIR}/include/proj7")
include_directories(${GDAL_INCLUDE_DIRS})

# 将源代码添加到此项目的可执行文件。
add_executable (${PROJECT_NAME} main.cpp ${GDAL_INCLUDE})
# message(STATUS "    include path: ${GDAL_INCLUDE}")

# 链接OpenCV与GDAL库
target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBS})
target_link_libraries(${PROJECT_NAME} ${GDAL_LIBRARY})

# 拷贝GDAL_DLL到执行项目目录下
file(GLOB_RECURSE GDAL_DLLS "${GDAL_DIR}/bin/*.dll")
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E copy_if_different
        ${GDAL_DLLS} $<TARGET_FILE_DIR:${PROJECT_NAME}>)

4.1.4.1 Cmakelist添加静态库

只需要把上面添加动态库流程的最后一步“拷贝GDAL_DLL到执行项目目录下”,这一步去掉就行了。

4.2 linux系统下导入第3方库

4.2.1 CmakeList

和windows下的一样,因为CmakeList就是为了实现跨平台的。

4.2.2 makefile

[1] 王道训练营的视频课
[2]makefile 完美教程_makefile教程_WittXie的博客-CSDN博客
[3] Makefile基础教程_makefile菜鸟教程-C文档类资源-CSDN文库

5 安装gdal库

5.1 Clion安装GDAL库

5.1 成功安装

按照下面的流程进行gdal的安装,clion中使用gdal的辛酸历程_gdal clion 配置_jayce_tang的博客-CSDN博客,还是会报错
在这里插入图片描述
之后百度发现报这个错是因为确实dll动态链接库:将libgdal.dll文件放到exe同级目录,执行成功。
在这里插入图片描述

CLion程序编译错误 0xC0000135_clion编译出现链接问题怎么解决_Cliven_的博客-CSDN博客

参考:
[1] clion中使用gdal的辛酸历程_gdal clion 配置_jayce_tang的博客-CSDN博客
[2] VS2017编译配置GDAL——超详细,适合初学者!!!_vs编译gdal_长安游的博客-CSDN博客

5.1.2 核心要点

网上的教程一般都是基于VS的,实际上前面的编译无论是VS还是Clion都应该是一样的。
我们自己无法编译,就用别人编译好的文件。
然后在Clion中进行配置。

5.2 VS软件环境安装gdal库

自己在vs2019上成功执行了下面程序,安装流程是参考的这个博客,里面唯一的错误就是lib库不用配置到环境变量中,而是要把bin目录下的.dll库放到生成的.exe文件的同级目录,非常好!成功了!!!
C++下GDAL的详细使用案例(含项目配置、tif读取为cv::Mat、Mat保存为tif)_c++ gdal_万里鹏程转瞬至的博客-CSDN博客

5.2.1 使用配置好的环境读取栅格信息(已成功执行)

// 获取栅格信息
#include <iostream>
#include <gdal_priv.h>
#include <gdal_alg_priv.h>
#include <gdal.h>
using namespace std;

int main() {
	//注册所有的驱动
	GDALAllRegister();
	//设置支持中文路径和文件名
	//CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); 

	//打开文件
	string file_path_name = "E:/data/GF2_PMS2_E113.8_N38.8_20201216_L1A0005315319/GF2_PMS2_E113.8_N38.8_20201216_L1A0005315319-PAN2.tiff";
	GDALDataset* poDataset = (GDALDataset*)GDALOpen(file_path_name.c_str(), GA_ReadOnly);
	if (poDataset == NULL)
	{
		cout << "指定的文件不能打开!" << endl;
		return 0;
	}

	// 获取波段信息
	GDALRasterBand* poBand = poDataset->GetRasterBand(1);
	int nXSize = poDataset->GetRasterXSize();
	int nYSize = poDataset->GetRasterYSize();

	cout << "width = " << nXSize << endl;
	cout << "height = " << nYSize << endl;

	// 获取投影参考系
	string projection = poDataset->GetProjectionRef();
	cout << "Projection = " << projection << endl;

	// 获取投影坐标范围
	double geoTransform[6];
	poDataset->GetGeoTransform(geoTransform);
	double minX = geoTransform[0];
	double minY = geoTransform[3] + nXSize * geoTransform[4] + nYSize * geoTransform[5];
	double maxX = geoTransform[0] + nXSize * geoTransform[1] + nYSize * geoTransform[2];
	double maxY = geoTransform[3];
	cout.setf(ios::fixed);
	cout.precision(8);
	cout << "X-axis minimum:" << minX << ",\nY-axis minimum:" << minY << ",\nX-axis maximum:" << maxX << ",\nY-axis maximum:" << maxY << endl;

	// 读取数据
	int* pafScanline = new int[nXSize];
	for (int i = 0; i < nYSize; i++) {
		poBand->RasterIO(GF_Read, 0, i, nXSize, 1, pafScanline, nXSize, 1, GDT_Int16, 0, 0);
	}

	delete[] pafScanline;

	//关闭栅格文件
	GDALClose(poDataset);

	return 0;
}

5.2.2 使用配置好的环境读取shp文件(已成功执行)

// 这个文件是读取shp的正确文件,用来验证配好的gdal库能不能用

#include "ogrsf_frmts.h"
#include <iostream>
using namespace std; 

int main()
{
    GDALAllRegister();
    GDALDataset* poDS;
    CPLSetConfigOption("SHAPE_ENCODING", "");  //解决中文乱码问题
    //读取shp文件
    poDS = (GDALDataset*)GDALOpenEx("E:\\data\\ZhongxianShp\\Zhongxian.shp", GDAL_OF_VECTOR, NULL, NULL, NULL);

    if (poDS == NULL)
    {
        cout << "ok";
        return 0;
    }

    OGRLayer* poLayer;
    poLayer = poDS->GetLayer(0); //读取层
    OGRFeature* poFeature;

    poLayer->ResetReading();
    int i = 0;
    while ((poFeature = poLayer->GetNextFeature()) != NULL)
    {
        //if (poFeature->GetFieldAsDouble("AREA") < ) continue; //去掉面积过小的polygon
        i = i++;
        cout << i << "  ";
        OGRFeatureDefn* poFDefn = poLayer->GetLayerDefn();
        int iField;
        int n = poFDefn->GetFieldCount(); //获得字段的数目,不包括前两个字段(FID,Shape);
        for (iField = 0; iField < n; iField++)
        {
            //输出每个字段的值
            cout << poFeature->GetFieldAsString(iField) << "    ";
        }
        cout << endl;
        OGRFeature::DestroyFeature(poFeature);
    }
    GDALClose(poDS);
    system("pause");
    return 0;
}

[1] windows下编译、安装及使用gdal-2.4.2_gdal2.4安装_草丛中的蝈蝈的博客-CSDN博客
[1] GDAL-3.4.0库 C++版编译_编译好的gdal_lufengok的博客-CSDN博客

5.3 linux环境下安装gdal库

5.4 尝试实现的几个教程案例

【1】c++ GDAL读取shapefile文件_gdal 打开shapefile文件_Chaoying.的博客-CSDN博客

【2】(433条消息) 结合C++和GDAL实现shapefile(shp)文件的读取_weixin_33675507的博客-CSDN博客

// 在lx的vs中环境已经运行成功了,代码没问题
#include "ogrsf_frmts.h"
#include <iostream>
using namespace std;

int main()
{
    GDALAllRegister();
    GDALDataset* poDS;
    CPLSetConfigOption("SHAPE_ENCODING", "");  //解决中文乱码问题
    //读取shp文件
    poDS = (GDALDataset*)GDALOpenEx("E:\\data\\Zhongxian\\Zhongxian.shp", GDAL_OF_VECTOR, NULL, NULL, NULL);

    if (poDS == NULL)
    {
        cout << "ok";
        return 0;
    }

    OGRLayer* poLayer;
    poLayer = poDS->GetLayer(0); //读取层
    OGRFeature* poFeature;

    poLayer->ResetReading();
    int i = 0;
    while ((poFeature = poLayer->GetNextFeature()) != NULL)
    {
        //if (poFeature->GetFieldAsDouble("AREA") < ) continue; //去掉面积过小的polygon
        i = i++;
        cout << i << "  ";
        OGRFeatureDefn* poFDefn = poLayer->GetLayerDefn();
        int iField;
        int n = poFDefn->GetFieldCount(); //获得字段的数目,不包括前两个字段(FID,Shape);
        for (iField = 0; iField < n; iField++)
        {
            //输出每个字段的值
            cout << poFeature->GetFieldAsString(iField) << "    ";
        }
        cout << endl;
        OGRFeature::DestroyFeature(poFeature);
    }
    GDALClose(poDS);
    system("pause");
    return 0;
}

【3】 C++调用GDAL实现栅格数据的读取_c++ 调用gdal_三千思丶的博客-CSDN博客

【4】GDAL C++开发总结(一)获取影像任一点坐标,对该点坐标进行坐标转换,如投影坐标转换为地理坐标,UTM转WGS84_c++ gdalallregister

// 在lx的vs环境中已经运行成功,代码没问题
#include <iostream>
#include <gdal_priv.h>
#include <gdal_alg_priv.h>
#include <gdal.h>
using namespace std;

int main() {
	//注册所有的驱动
	GDALAllRegister();
	//设置支持中文路径和文件名
	//CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); 

	//打开文件
	string file_path_name = "E:/data/GF2_PMS2_E113.8_N38.8_20201216_L1A0005315319/GF2_PMS2_E113.8_N38.8_20201216_L1A0005315319-PAN2.tiff";
	GDALDataset* poDataset = (GDALDataset*)GDALOpen(file_path_name.c_str(), GA_ReadOnly);
	if (poDataset == NULL)
	{
		cout << "指定的文件不能打开!" << endl;
		return 0;
	}

	// 获取波段信息
	GDALRasterBand* poBand = poDataset->GetRasterBand(1);
	int nXSize = poDataset->GetRasterXSize();
	int nYSize = poDataset->GetRasterYSize();

	cout << "width = " << nXSize << endl;
	cout << "height = " << nYSize << endl;

	// 获取投影参考系
	string projection = poDataset->GetProjectionRef();
	cout << "Projection = " << projection << endl;

	// 获取投影坐标范围
	double geoTransform[6];
	poDataset->GetGeoTransform(geoTransform);
	double minX = geoTransform[0];
	double minY = geoTransform[3] + nXSize * geoTransform[4] + nYSize * geoTransform[5];
	double maxX = geoTransform[0] + nXSize * geoTransform[1] + nYSize * geoTransform[2];
	double maxY = geoTransform[3];
	cout.setf(ios::fixed);
	cout.precision(8);
	cout << "X-axis minimum:" << minX << ",\nY-axis minimum:" << minY << ",\nX-axis maximum:" << maxX << ",\nY-axis maximum:" << maxY << endl;

	// 读取数据
	int* pafScanline = new int[nXSize];
	for (int i = 0; i < nYSize; i++) {
		poBand->RasterIO(GF_Read, 0, i, nXSize, 1, pafScanline, nXSize, 1, GDT_Int16, 0, 0);
	}

	delete[] pafScanline;

	//关闭栅格文件
	GDALClose(poDataset);

	return 0;
}

6 安装Opencv库

6.1 vs2019安装opencv库

1、主要参考下面两个文档实现:
opencv安装与配置vs2019_opencv vs2019_平杨猪的博客-CSDN博客
VS2019 OpenCV安装与配置教程_vs2019安装opencv_XHR-想象之中的博客-CSDN博客

2、上面安装的opencv包没有xfeature2d.hpp模块,这是opencv的一个扩展库,在使用SOUR算法的时候需要用到这个扩展库,扩展库的安装见下面链接:
OpenCV 没有xfeatures2d解决方法_opencv_安静55668-DevPress官方社区

3、根据上面的步骤来看比较麻烦,第2步缺少opencv_xfeatures2d453.lib等文件,在运行surf算法的时候怎么都跑不通,之后找到了下面的这个编译好的库。opencv库包含两个库,一个是opencv库,另一个是opencv_contrib库,相当于是基础opencv的拓展库。
opencv453+vs2019编译的动态库资源-CSDN文库

安装所有包都一样,就3步:
1、找到第3方库的包;
2、vs里配置头文件目录和静态库文件目录;
3、将动态库.dll放到可执行程序.exe的同级目录或者环境变量中。

// 测试opencv库是否可以正常使用的代码
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int maincecv(int argc, char** argv)
{
	//VideoCapture cap(0);
	VideoCapture cap("D:/resoure/表彰大会.mp4");
	if (!cap.isOpened())
	{
		printf("Can not open a camera\n");
		return -1;
	}

	while (true)
	{
		Mat frame;
		cap >> frame;
		if (frame.empty())
			break;

		imshow("frame", frame);

		// 非均值滤波
		Mat robot = (Mat_ <int>(2, 2) << 1, 0, 0, -1);
		Mat result;
		filter2D(frame, result, CV_32F, robot, Point(-1, -1), 127, BORDER_DEFAULT);
		convertScaleAbs(result, result);
		imshow("robot filter", result);

		//等待 30 秒,如果按键则推出循环
		if (waitKey(30) >= 0)
			break;
	}

	waitKey(0);
	return 0;
}

总结

(1)理清c++程序执行流程:5步:准备好编程所需文件、搭好环境、编程、编译、执行
(2)理清编译软件有哪些:
(3)理清编译流程分为哪4步:
(4)理清什么是动态库和静态库:
(5)理清在一个项目中如何使用第三方库,在c++程序执行的4步中都需要考虑第3方库:准备编程所需文件时要考虑第三方库是源码还是编译好的文件(是源码还需要先将第3方库进行编译),搭建环境的时候需要配置好第三方库,编程时引用第三方库头文件并使用第3方库函数,编译时考虑怎么打包,执行时考虑用不用第三方库的动态库的.dll文件。
(6)理清引入第3方库(导包):就是引入动态库或静态库,也可以是源码,这3种方式选择一种就行,但是一般不用直接用第三方库的源码,拿到了第3方库的源码也会先编程成动态库或静态库。
(7)windows中使用静态库的方法导入第3方库,就是配置好.h头文件和.lib文件这两个文件。
(8)windows中使用静态库的方法导入第3方库,就是配置好头文件和.lib文件这两个文件,在静态库的基础上再把.dll动态库文件放到.exe同级目录(debug和release模式下exe在不同文件夹)。
(9)linux中使用静态库的方法导入第3方库,就是配置好.h头文件和.a文件这两个文件。
(10)linux中使用动态库的方法导入第3方库,就是配置好.h头文件和.a文件这两个文件,在静态库的基础上再把.so动态库文件放到.out同级目录。
(11)windows和linux使用源码的方式导入第3方库,直接放到项目目录下就行,一般不用源码,而是提前把源码编译成动态库或者静态库的方式,再使用动态库或者静态库的方法导入第三方库。
(12)windows和linux导入第3方库都一样:就是导入动态库或静态库;
(13)windows引入第3方库两种方式:一是使用Cmakelist文件组织、类似于maven;二是在vs、clion等软件中直接配置。
(14)linux中引入第3方库的两种方式:一是使用makefile文件;二是使用Cmakelist文件组织。
(15)

(16)理清在不同集成软件中如何使用第三方库:

参考文献

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c++下程序的运行(第3方库的安装及安装gdal) 的相关文章

  • Mysql 事务(标贝科技)

    文章目录 事务InnoDB对ACID的支持隔离级别不同隔离级别下读读取数据可能出现的情况不可重复读和幻读区别 redo log xff08 共享表空间 xff09 redo log block刷redo log策略 xff1a innodb
  • Ubuntu20.04运行Vins-fusion

    因已安装ROS noetic xff0c eigen xff0c opencv及ceres等库 xff0c 这部分环境配置就不细讲 xff0c 直接下载VINS FUSION的代码库 下载编译 cd span class token ope
  • 坐标系之间的转换关系(ECEF、LLA、ENU)

    一 坐标系简介 1 ECEF坐标系 也叫地心地固直角坐标系 其原点为地球的质心 xff0c x轴延伸通过本初子午线 xff08 0度经度 xff09 和赤道 xff08 0deglatitude xff09 的交点 z轴延伸通过的北极 xf
  • Python画图常用的颜色及标识

    matplotlib中color可用的颜色 xff1a aliceblue F0F8FF antiquewhite FAEBD7 aqua 00FFFF aquamarine 7FFFD4 azure F0FFFF beige F5F5DC
  • .npy文件打开方式

    在用evo评测slam算法定位精度时 xff0c 使用 save results a zip 生成的结果中包含的 npy文件 xff0c 如果要查看里面详细的数值 xff0c 则可通过以下方式打开文件并查看 1 xff09 找到要查看的 n
  • IMU误差模型简介及VINS使用说明

    1 IMU误差来源 2 IMU噪声模型 Noise and Bias kalibr中的imu noise model 参考 xff1a https github com ethz asl kalibr wiki IMU Noise Mode
  • 泰勒公式(泰勒展开式)通俗介绍+本质详解

    比较通俗地讲解一下泰勒公式是什么 泰勒公式 xff0c 也称泰勒展开式 是用一个函数在某点的信息 xff0c 描述其附近取值的公式 如果函数足够平滑 xff0c 在已知函数在某一点的各阶导数值的情况下 xff0c 泰勒公式可以利用这些导数值
  • Leetcode ->94 二叉树的中序遍历

    题目 算法思路及代码实现 span class token macro property span class token directive hash span span class token directive keyword inc
  • Unix、UTC、GPS时间戳及转换

    UTC时间 UTC时间的英文全称 xff1a Universal Time Coordinated xff0c 中文名称 xff1a 协调世界时 俗的理解为 xff0c 这个时间是全世界通用的 xff0c 即全世界都公用的一个时间 可以认为
  • 自动驾驶中地图匹配定位技术总结

    引言 汽车定位是让自动驾驶汽车知道自身确切位置的技术 xff0c 在自动驾驶系统中担负着相当重要的职责 汽车定位涉及多种传感器类型和相关技术 xff0c 主要可分为卫星定位 惯性导航定位 地图匹配定位以及多传感器融合定位几大类 其中地图匹配
  • Firefox 常用扩展插件及脚本推荐 打造你不一样的Firefox

    前言 xff1a 进入2011年以来 xff0c 整个浏览器领域的竞争越发激烈 xff0c 随着IE9正式版的发布 Chrome Opera等浏览器厂商也相继更新 发布了新的版本 经过多次跳票之后 xff0c FireFox4 0正式版终于
  • mysql 锁(标贝科技)

    标贝科技 https ai data baker com source 61 qwer12 填写邀请码fwwqgs xff0c 每日免费调用量还可以翻倍 mysql 锁 锁类型 类型 表级锁 xff1a 开销小 xff0c 加锁快 xff1
  • STM32G4学习笔记之DAC+FMAC

    1 高性能DAC G4系列一共有四个DAC 前两个为低速采集DAC xff08 1MHz xff09 xff0c 后两个为高速 可达15MHz DAC1 DAC2的采样速率最大为1MHz xff0c DAC3 DAC4的采样速率最大为15M
  • 逆变电路之单极性调制与双极性调制

    就调制脉冲的极性而言 单相全桥逆变器pwm调制技术主要分为单极性调制与双极性调制 下面就其调制原理分别做简单的介绍 1 单极性调制 单极性调制的原理如图所示 调制信号ur为正弦波 载波uc在ur的正半周为正极性的三角波 在ur的负半周 为负
  • OTL电路与OCL功放电路的区别

    一 OTL电路 OTL xff08 Outputtransformerless xff09 电路是一种没有输出变压器的功率放大电路 过去大功率的功率放大器多采用变压器耦合方式 xff0c 以解决阻抗变换问题 xff0c 使电路得到最佳负载值
  • 运放失真罪魁祸首之压摆率和增益带宽积

    1 什么叫压摆率 xff1f 做1pps驱动电路 1 xff0c 1PPS xff1a 秒脉冲英文全称 xff1a Pulse Per Second 1pps概念 要求上升沿 5ns xff0c FPGA输出的信号用运放跟随增强驱动后 xf
  • 电源反馈电路设计经验(PC817光耦隔离+TL431)

    身边的很多小伙伴好像都对电源的反馈电路的计算以及原理不太了解 xff0c 这里给大家系统的讲解一下 xff1a 废话不都说 xff0c 咱们直接上干货 在分析电路前需要注意的关键点 1 光耦的输入端 xff08 二极管端 xff09 的电流
  • 一分钟带你了解常用的V-I、I-V转换电路

    下面我将给大家介绍6种常用的V I I V转换电路 1 0 xff0d 5V 0 xff0d 10mA的V I变换电路 图1是由运放和阻容等元件组成的V I变换电路 xff0c 能将0 5V的直流电压信号线性地转换成0 xff0d 10mA
  • 奈奎斯特采样定理-为什么采样率需要时被测信号最高频率的两倍

    奈奎斯特采样定理 采样定理在1928年由美国电信工程师H 奈奎斯特首先提出来的 xff0c 因此称为奈奎斯特采样定理 1933年由苏联工程师科捷利尼科夫首次用公式严格地表述这一定理 xff0c 因此在苏联文献中称为科捷利尼科夫采样定理 19
  • 傅里叶变换简单解析

    这里有两个频率 一个是信号本身的频率 位1 3sec 一个下面矢量绕圆的频率 为1 0 79sec 下面这个频率是我们可以改变的 这就是所谓的窗 即我们选取多长的一段信号用来进行傅里叶变换分析 当截取的窗的周期等于信号周期1 3sec时 就

随机推荐

  • 组合逻辑与时序逻辑

    我前段时间对这两个逻辑的概念有点混淆 xff0c 所以就百度查看了一下 xff0c 排名第一的结果就出现了这样的解释 xff1a 数字电路根据逻辑功能的不同特点 xff0c 可以分成两大类 xff0c 一类叫组合逻辑电路 xff08 简称组
  • AD2020如何安装库

    首先快捷键op打开下面界面 然后找到库的位置安装就可以了
  • 白话Android音频系统原理(上)(标贝科技)

    白话Android音频系统原理 xff08 上 xff09 一 基本原理二 初始化准备工作三 播放流程四 录音流程 标贝科技 https ai data baker com source 61 qwer12 填写邀请码fwwqgs xff0
  • keil 工程头文件包涵及结构体重定义问题

    最近在写一个太阳能电池控制板的项目 xff0c 这两天真是收获颇丰 xff0c 把指针又从新学了一遍 xff0c 还是项目坑死人啊啊啊啊啊 下面是我在建立工程时遇到的问题 xff1a 1 头文件包涵问题 xff1a 原先写的程序都是小程序
  • Openmediavault 4.1.3 镜像下载地址

    Openmediavault 4 1 3 镜像下载地址 https nchc dl sourceforge net project openmediavault 4 1 3 openmediavault 4 1 3 amd64 iso
  • 【leetcode】【77】Combinations

    一 问题描述 Given two integers n and k return all possible combinations of k numbers out of 1 n For example If n 61 4 and k 6
  • 激光雷达介绍

    全球汽车行业正在进行自动化变革 xff0c 这将彻底改变交通运输的安全和效率水平 戴姆勒在S级豪华车型中引入L3级自动驾驶 xff08 L3 xff0c 在特定条件下自动驾驶 xff0c 人类驾驶员一旦被请求就会随时接管 xff09 是自动
  • get请求 包括username和password

    方法一 xff1a public static String wisdomNetMessagePlat String sn String encoding throws Exception String result 61 34 34 St
  • Arduino控制L298N

    一般做智能小车或者DIY开发的童鞋需要用到Arduino这狂开发板 xff0c 作为一名好奇心很强的软件开发人员 xff0c 我自然也想尝尝鲜特别是利用Arduino做一些人机交互的项目 xff0c 如果结合了Kinect AR增强现实 x
  • gitlab打tag的作用,以及如何基于tag切分支

    在 GitLab 中 xff0c Tag 是将 Git 项目中特定的提交标记为版本的一种方式 Tag 能够用于标记发布的版本 xff0c 以便于对代码的每个版本进行管理和追踪 打 Tag 的作用主要有以下几点 xff1a 标记版本发布 xf
  • 解析包含用户名密码的FTPURL

    include lt stdio h gt include lt string h gt void parse ftpurl char url char user char passwd char ipaddr uint port char
  • nvidia jetson xavier nx Deepstream Yolov3示例模型运行

    最近在玩nvidia jetson xavier nx的板子 xff0c 特在此做一些笔记 1 进入sample目录 cd opt nvidia deepstream deepstream sources objectDetector Yo
  • go-mysql-elasticsearch+mysql 同步 ElasticSearch(标贝科技)

    标贝科技 https ai data baker com source 61 qwer12 填写邀请码fwwqgs xff0c 每日免费调用量还可以翻倍 一 Elasticsearch xff1a https www elastic co
  • Intel Realsense D400系列相机自校准细节,减少踩坑!!

    自校准 xff08 对任意环境非白墙 注意距离0 4 2米之间 xff0c 深度 xff08 相机拍摄内容中物体所占空间 xff09 50 xff09 xff1a 打开Intel realSense viewer xff1a 连接设备 xf
  • QT实现NMea截取指定片段字符串——$GNGGA(小白第一次编,后期有机会完善代码,高勿)

    总体思路 xff1a 1 读取所有数据 xff08 readAll xff08 xff09 xff09 QByteArray readbuf 61 serial gt readAll 2 查找标志位 xff08 QString中使用inde
  • linux c&&c++关于赋值问题(char*传给另一个char*)

    仅列出四种 xff0c 欢迎补充 xff01 方法一 xff1a 直接 char buf1 61 char buf2 xff0c xff08 xff01 xff01 xff01 这里的赋值是将buf2的地址赋给了buf1 xff0c 此后b
  • B6AC使用说明

    1 接线方式 接线如下图所示 xff0c 如果电池是XT60 xff0c 可以用接鳄鱼夹子的T插夹在XT60的接口上 2 设置方法 2 1 锂电池充电 1 xff09 Batt Type gt 切换选择 LiPo BATT gt Enter
  • 整数转换为字符串

    include lt stdio h gt 反转字符串 char reverse char s char temp char p 61 s p指向s的头部 char q 61 s q指向s的尾部 while q 43 43 q q 交换移动
  • 【工具使用】Modbus Poll软件使用详解

    软件介绍 Modbus Poll是一个模拟Modbus协议主机的上位机软件 xff0c 主要用于模拟测试跟其他从机设备通信的过程 与之成套存在的另一个软件 Modbus Slave xff0c 则是模拟Modbus协议从机的上位机软件 该软
  • c++下程序的运行(第3方库的安装及安装gdal)

    C 43 43 安装第三方库 1 概览2 编译 xff0c 首先要熟悉程序编译过程 xff08 预处理 gt 编译 gt 汇编 gt 链接 xff09 2 1 编译流程4步2 1 1 1 预处理2 1 2 2 编译2 1 3 3 汇编2 1