Running programs under c++ (installation of third-party libraries and installation of gdal)

C++ install third-party libraries

1 Overview

Installing a third-party library is nothing more than 4 steps:
(1) Compile the third-party library source code into a dynamic library or static library (you can directly download the library compiled by others);
(2) Configure it in the development tool so that it can be referenced;
( 3) Reference and programming in the code;
(4) Package into executable files.

There are three questions that need to be clarified:
(1) What are the forms of the third library, and what are the forms in Linux and Windows?
(2) How to configure third-party libraries with different development tools?
(3) How to use compilation and packaging tools?

Learning programming means learning first:
(1) Programming language;
(2) Various tools (integration tools vs, publishing tool git, database tool mysql, etc.);
(3) Various third-party libraries can also be counted as tools, Some functions written by others.
(4) Solve practical problems;

2 To compile, you must first be familiar with the program compilation process (preprocessing->compile->assembly->link)

2.1 4 steps of compilation process

Reference document:
Using MinGW to compile and run a C++ program on the command line under Windows

2.1.1 1 Preprocessing

Preprocessing mainly processes preprocessing commands such as "#include" and "#define" in source files. The
main tasks completed by preprocessing are:
(1) Delete #define and expand macros;
(2) Process conditional compilation instructions and preprocessing programs Determine the conditions first, and then modify the source code according to the conditions;
(3) Delete comments;
(4) Add line numbers and file name identifiers to facilitate debugging
(5) Delete "#include" and insert the corresponding header file;
use g++ -E test.cpp -o test.i command, get the test.i file after preprocessing

Insert image description here

2.1.2 2 Compilation

In the process of generating assembly code, use the command g++ -S test.i -o test.s to generate the assembly file test.s file. Of course, you can also get the assembly file directly from the test.cpp file.
Insert image description here

2.1.3 3 Assembly

Convert assembly code into machine instructions and generate target binary code.
Use the command g++ -c test.s -o test.o to generate the test.o file

2.1.4 4 links

Convert the target file into an executable file by linking the library file.
Use the command g++ test.o -o test.exe -L to specify the path to the required library file, where L is the abbreviation of link.
Insert image description here

Of course, under normal circumstances, you can directly use g++ test.cpp -o test to generate an executable program without the step-by-step operation above.

2.2 Running C++ programs in Linux and running programs in Windows

2.2.1 Compiling and running c++ programs in Windows

As in Section 2.1, in the 4 steps of compilation, you can directly use g++ test.cpp -o test to generate an executable program.

Practical case study of using MinGW to compile and run C++ programs on the command line under Windows

2.2.2 Compiling and running C++ programs in Linux (how to write a C++ program)

The general process of developing and running C++ programs on the Linux platform is not much different from that under Windows
1. Prepare third-party libraries and data, and some supporting files such as .h files. These files are generally placed together, or their relative positions are fixed;
2. Write a .cpp file with C++ code in it;
3. Compile the file and generate an executable file, which is .exe in Windows and .out file or a file without a suffix under Linux;
4. Run the executable file, Under Linux, run executable files through commands. ./yourprocess directly uses this to execute the yourprocess program in the current directory;

To make the compiled code run on Linux, we need to use GCC
to precompile: precompile hello.c and stdio.h to hello.i and
compile: compile hello.i to hello.s, which is an assembly file.
Assembly: Translate hello.s into machine instructions hello.o (.o object file)
Linking: Link various required libraries and other object files (not required by the hello program) to obtain the executable file hello.out (equivalent to windows .exe)

Compiling and running c++ programs on linux platform_Linux compiling cpp file case practice_Menglon's blog-CSDN blog

2.3 Debug mode and Release mode

debug means "troubleshooting, debugging", and release means "release, release";

Debug folder: Debugging – debugging is completed and the executable program is successfully generated, and failure data is returned upon failure.
Release folder: Release version – the executable program that needs to be released is released.

Debug version
Debug means "debugging". The Debug version is born for debugging. The compiler will add debugging auxiliary information when generating the Debug version of the program, and rarely optimizes it. The program is still "original".

You heard it right, not every program can be debugged. The program must contain additional auxiliary information to debug it, otherwise the debugger will not be able to start.
Release version
Release means "release". The Release version is the program that is finally handed over to the user. The compiler will do its best to optimize it to improve execution efficiency. Although the final running result is still what we expect, the underlying The execution process may have changed.

The compiler will also try to reduce the size of the Release version and remove all useless data, including debugging information.

In the end, the Release version is a small, compact, very pure program that is built for users.

Insert image description here

2.4 What are the compilation tools (different software is used under different systems. The g++ mentioned above can be replaced by other compilation tools here)

First of all, these are the well-known friends, MSVC, GCC, Cygwin, MingW (English pronunciation of Cygwin and MingW), and there are also some niche and new talents, such as ICC (Intel C/C++ Compiler), BCC (Borland C/C++ Compiler) , almost disappeared), RVCT (ARM's assembly/C/C++ compiler, built into ARM's IDE-RVDS), Pgi compiler... In fact, there is a long list, as long as we are familiar with the most powerful ones commonly used That's it.

A must-read for lx, this document is so good, so good, let’s take a look at the relationship between gcc/g++/MingW/MSVC and make/CMake - Zhihu’s relatively easy-to-use c++ compiler (easy-to-use C++ compiler
)

2.4.1 What are compilation tools?

1 G++ from the GNU Organization (linux system)

GCC/G++ can be considered the same, and can be compiled with g++ under both windows and linux systems.

Install gcc/g++_linux install g++_WW on Linux virtual machine

2 Mingw/MSVC for Windows (specifically for Windows systems, the two softwares are different, just use one)

MinGW (Minimalist GNU for Windows) is a collection of freely available and freely redistributable Windows-specific header files and import libraries using the GNU toolset, allowing you to generate native Windows programs on the Windows platform without the need for a third-party C runtime ( C Runtime) library.

When using MinGW, you actually run some g++ commands because MinGW integrates the g++ tools of the GNU organization.

When using software such as Clion, you also need to configure MinGW or MSVC;

Runtime library: A collection of basic functions that support program running, usually a static library lib or a dynamic library dll.

MSVC is the third-party C runtime library mentioned above: the VC runtime library developed by Microsoft and integrated by the Visual Studio IDE. So when we use VS, it comes with the MSVC compiler.

So you can see that both MinGW and MSVC are supported by Windows C/C++ language compilation. Just choose one of the two when configuring the environment.

Detailed steps to download and install MinGW-w64 (windows version of c/c++ compiler gcc, real and usable in win10)_jjxcsdn's blog-CSDN blog

3 LLVM’s clang/clang++ (compilation software for Apple IOS systems)

With the previous article, you should know LLVM and clang without explanation.

LLVM is a framework system for constructing compilers, written in C++, and is used to optimize the compile-time, link-time, and run-time of programs written in any programming language. time) and idle time (idle-time), remain open to developers and compatible with existing scripts.

The LLVM project was launched in 2000 and was initially hosted by Dr. Chris Lattner of UIUC University in the United States. In 2006, Chris Lattner joined Apple Inc. and devoted himself to the application of LLVM in Apple's development system. Apple is also a major funder of the LLVM initiative.

Currently, LLVM has been adopted by major companies such as Apple IOS development tools, Xilinx Vivado, Facebook, and Google.

4 Make and CMake (CMake is a cross-platform software based on a compiler. It will select the correct compiler based on windows or linux. Make is a higher-level tool than g++, and CMake is a higher-level tool than Make. .)

With the compiler GCC and so on, why is there a build generator called make? It is also a cliché.

Compiling hello.c is very simple, just

$ gcc hello.c

That's fine, but when the project grows larger, suppose hello.c depends on ac and bc, and ac depends on the library w.lib. Do we have to rewrite the gcc compilation command line every time we compile?

Therefore, GNU invented the tool software make. You can write a makefile to specify a specific project build process. When the code of a file in the project changes, we only need to remake it.

The make tool can be regarded as an intelligent batch processing tool, which itself does not have compilation and linking functions.

But make still has many shortcomings, such as

Make is universal for Unix-like systems, but it is not friendly to Windows systems (cannot be cross-platform). Of course, make can also be installed in Windows systems, but makefiles created under Windows cannot be used on Linux.

The syntax of make is simple, which leads to the limitation of its functions.
Different compilers have different syntax rules. If the syntax of the makefile written is suitable for GCC, it is not suitable for MSVC
. Therefore, CMake came into being.

CMake is a higher-level tool than Make. Make writes a makefile corresponding to the compiler to achieve compilation, while CMake writes an independent CmakeList.txt file, which then selects a suitable build generator based on the current system environment. (such as VS or make), then translate CmakeList.txt into a suitable file, and then further call the system compiler to build the project.

Summary:
(1) The make software has only one function:
to solve the problem of insufficient g++ functions when the project relies on many third-party libraries. It is a software based on g++. It is used to sort out the dependent libraries and then call g++ Tools are used to compile, make up for the shortcomings of g++, and realize the function of maintaining third-party libraries .
(2) Cmake software has only one function:
to make up for the defect that make cannot be cross-platform, and to realize the two functions of cross-platform and maintaining third-party libraries .
(3) Difference between the two:
Difference 1: Make software can only be used for Linux systems, and some say it can be used for Windows, but it cannot use one makefile file. Cmake software can be used across platforms; Difference 2: Make software writes
makefile files Implement compilation; Cmake writes and executes CmakeList.txt to implement compilation.

A must-read for lx, this document is so good, so good, let’s take a look at the relationship between gcc/g++/MingW/MSVC and make/CMake - Zhihu

A must-read for lx, the difference and connection between Makefile and Cmake_The difference between cmake and makefile_There is an error in the introduction of Cmake in this document. It also supports windows, not just linux

Makefile operation tutorial under windows platform_windows makefile_Shuai Debuyaode's blog-CSDN blog

A detailed introduction to CMake from scratch_bilibili_bilibili

[cmake tutorial] Introduce external third-party libraries into your project (take the real project partio as an example)_bilibili_bilibili

5 What compilation tools are used for Windows and Linux respectively?

(1) Use Mingw or MSVC under Windows, and know Cmake;
(2) Use g++, make, and Cmake under Linux

6. What exactly is needed for compilation has nothing to do with programming software?

(1) When we compile a program, we use g++ compilation software or Mingw software, not software such as vs, vscode, and clion.
(2) When we write the program, we just use txt. When compiling the software, we directly use the Mingw software, so that we can get the executable file.
(3) The function of vs, vscode, and clion is to integrate Notepad (or other text editor) and the compilation software Mingw. It is an integrated tool. You can change the compilation software Mingw or MSVC in vs, vscode, and clion.

7 makefile and Cmakelist

As mentioned in Section 4 above, they are all files, used for processing by make software and Cmake software respectively.

(1) Makefile
The Makefile file describes the compilation rules of C/C++ projects under the Linux system. It is used to automatically compile C/C++ projects. Once the Makefile is written, only one make command is needed, and the entire project will start to be automatically compiled, and there is no need to manually execute GCC commands.
(2) Cmakelists
CMake configures the project's build system through CMakeLists.txt, and uses the cmake command line tool to generate the build system and perform compilation and testing. It is much more efficient than manually writing the build system (such as Makefile). For C/C++ project development, it is very worth learning and mastering.

Makefile tutorial: 1-day introduction to Makefile writing

CMakeLists Tutorial (Practical Summary)_A blog for driving wine but not driving - CSDN Blog
CMake Application: Complete Guide to CMakeLists.txt - Zhihu

8 4 basic knowledge of environment operation that need to be learned

(1) How to write 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调试工具等结合在一起的一个软件,不要想的多牛逼。

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

However, when I usually use software such as Visual Studio, I do not come into contact with the compilation process, because VS is a highly integrated development environment (IDE, Integrated Development Environment) that integrates a code editor, compiler, debugger and graphical user interface. All of the above The program compilation and linking processes are all carried out using one-step build.

We learn programming on integrated tools. In addition to the grammatical characteristics of the programming language itself, we also need to understand the use of integrated tools and use integrated tools to edit code to implement specific functions and solve practical problems.

I say important things three times:
You don’t need to integrate tools when programming. As long as you have a notepad or vim, you can program, but integrated tools are more convenient!
You don’t need to integrate tools when programming. As long as you have a notepad or vim, you can program, but integrated tools are more convenient!
You don’t need to integrate tools when programming. As long as you have a notepad or vim, you can program, but integrated tools are more convenient!

VS (Visual Studio) tool introduction

2.6 Summary of the meanings of various files

(1) Files in the compilation process:
.i is the file obtained after preprocessing in step 1 of the 4 steps of high-level language compilation;
.s assembly file test.s is obtained by compiling high-level language. The next step is to assemble it through this file. oMachine instruction file;
.oMachine instruction file, also called target binary code file;
.out executable file under Linux system, the same as
.exe file under Windows. .exe executable file under Windows;

(2) Third-party library files:
.h header file: used to declare third-party library classes and functions;
makefile file : used to compile c++ program source files in make software;
CmakeLists file : used to compile c++ program source files in Cmake software ;

Static libraries and dynamic libraries in windows and linux. For specific differences, see the introduction of library files in Chapter 3 below:
(2.1) In Windows:
.lib: Generate a c++ static library in Windows, a project to generate a static library in Windows, compile and generate After success, only one .lib file is generated.
.dll and .lib: The c++ dynamic library in Windows. The project to generate the dynamic library in Windows. After successful compilation, a .lib file and a .dll file are generated.

(2.2) In Linux:
.a file: The static library of the C++ language in the Linux system . The C++ static library in Linux is suffixed with .a (archive). Its function is to extract the static library from the static library when linking to generate an executable file. Copy the required content from the file into the final executable file.
.so file: The dynamic library of the C++ language in the Linux system . The dynamic library in Linux has the suffix .so (shared object). It does not copy all the required binary codes to the executable file during linking, but Copy some relocation and symbol table information, and obtain it from the dynamic library through the symbol table when needed when the program is running.

3. References to third-party libraries (only used in 3 stages, 1. When introduced during programming, no error will be reported; 2. When packaged and compiled into an executable file, no error will be reported, and the packaged program will execute normally; 3. When the program is executed, it will execute normally. )

3.1 3 problems that need to be solved in 3 stages

(1) When programming: how to reference third-party libraries when editing;
(2) When compiling: how to use third-party libraries when packaging and compiling executable programs.
(3) During execution: The program can be executed normally when executed.

3.2 Several functions that need to be implemented (implementing these functions will completely clarify the execution of the third-party library environment and C++ programs)

(1) Write the function of reading files and outputting them on Notepad, and compile it into an executable file without using vs, vscode, or clion.
(2) Call the third-party library on Notepad, opencv writes the function of reading the image, changing the size and saving it, and compiles it into an executable file and runs it normally.
(3) Call the third-party library on Clion and VS or vscode, opencv writes the function of reading the image, changing the size and saving it, and compiles it into an executable file and runs it normally. (Proficient in software applications)
(4) Implement the same three functions above in the Linux system.

3.3 What are third-party libraries?

3.3.1 What are third-party libraries?

I don’t know where the term third-party library comes from, but it generally refers to the program library provided by a third participant other than the developer or system/platform provider. Most open source software libraries are third-party libraries in software systems.
Development without using libraries at all was abandoned in the 1990s. The rise of the open source movement made third-party libraries the main library.
There are some very special libraries in the C++ field, such as the early STLport and the current Boost. They are like de facto standards for the language, and they can be seen in basically every program.
1. Introducing a third-party library means introducing a dynamic library or a static library. You can also introduce source code (but generally without source code, the source code will be compiled into a dynamic library or a static library).
2. Using a third-party library can save us from reinventing the wheel ourselves. In the process , directly using tools made by others can greatly improve development efficiency and simplify development difficulty.
3. But third-party libraries can also cause quite a few problems, mainly including:
(1) Version inconsistency. In the same software system, if two different versions of the same third-party library are referenced, problems will inevitably arise.
(2) The compilation options are inconsistent. Generally, in order to reduce compilation time, third-party libraries will participate in software compilation in the form of compiled .a/.lib. The compilation options of third-party libraries are different from those of the software system, and there will also be some potential problems. Especially x86/x64, ansi/utf-8 these options are different and cannot be used at all.
(3) The version management library becomes larger. In some large projects, there are often several G repositories, and each clone is very expensive. In fact, many of them are third-party libraries, libraries generated by different versions and different compilation options.

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

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

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

3.3.2 第3方库分为3种形式

(1)第3方库源代码,通过源代码使用,几乎不用这种方式;
(2)第3方静态库;
(3)第3方动态库;
可以自己编译第3方库源代码得到第3方动态库或者第3方静态库,也可以直接下载别人编译好的。一遍第3种方式最为常用。

3.3.3 第3方库由头文件和库文件组成

3.3.3.1 头文件

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

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

(1) Why can you use the declared function only by writing the included header file at the head of the program? There is no implementation content in the header file?

Because header files are related to library files, if you find the header file, you will find the library file.

First, you must be familiar with the program compilation process: preprocessing->compile->assembly->link;
Insert image description here

3.3.3.2 Library files (just use one of static library and dynamic library, don’t use both, both are ways of code sharing)

A library file is a type of object file, a static library is a relocatable object file, and a dynamic library is a shared object file.
When we actually use it, we only need to use one. For example, the opencv library can have dynamic libraries and static libraries. We only need to use one of them, not both.

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

(1) Library files are divided into dynamic libraries and static libraries:
**Static library:** In the linking step, the connector will obtain the required code from the library file and copy it to the generated executable file. This kind of library is called It is a static library, and its characteristic is that the executable file contains a complete copy of the library code; the disadvantage is that if it is used multiple times, there will be multiple redundant copies. That is, all instructions in the static library are directly included in the final generated EXE file. Create a new project to generate a static library in vs. After successful compilation and generation, only one .lib file will be generated.
**Dynamic Library:** A dynamic link library is a library that contains code and data that can be used by multiple programs at the same time. A DLL is not an executable file. Dynamic linking provides a way for a process to call functions that are not part of its executable code. The executable code for a function is located in a DLL that contains one or more functions that have been compiled, linked, and stored separately from the process that uses them. Create a new project to generate a dynamic library in vs. After successful compilation, a .lib file and a .dll file will be generated.

(2) So what is the difference between the above static library and the lib in the dynamic library?
Lib in the static library: This LIB contains the function code itself (that is, including the index of the function, including the implementation). The code is directly added to the program during compilation. Lib in the dynamic library: This LIB contains the DLL file and file where the function is located
. The function location information (index) in the function implementation code is provided by the DLL loaded in the process space at runtime.
In short, lib is used during compilation, and dll is used at runtime. If you want to compile the source code, you only need lib; if you want to run a dynamically linked program, you only need dll.

(3) The difference between static library and dynamic library in Linux and Windows:
Insert image description here

lx is very good, very good: the difference between dynamic libraries and static libraries, production and usage in windows and linux environments_windows linux dynamic library

3.3.3.3 Differences between header files and library files

Header files are declarations of classes and functions;
library files are the codes that store classes and functions.
Insert image description here
Insert image description here
lx is very good, very good, the difference between header files and library files, the difference between dynamic libraries and static libraries, the generation of dynamic and static libraries_the difference between header files and library files

3.3.3.4 Target file (cannot understand)

Before explaining static libraries and dynamic libraries, you need to briefly understand what an object file is. Target files are often organized according to a specific format. Under Linux, it is ELF format (Executable Linkable Format, executable linkable format), while under Windows it is PE (Portable Executable, Portable Executable).

There are usually three forms of target files:

(1) Executable target file. That is what we usually know as a binary file that can be run directly.

(2) Relocatable target files. Contains binary code and data that can be combined with other relocatable object files to create an executable object file.

(3) Share target files. It is a special relocatable object file that is linked at load or run time.

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

3.3.4 The difference between dynamic libraries and static libraries

3.3.4.1 Differences in execution between dynamic libraries and static libraries

0The most fundamental difference is the different stages of use:
when using a static library, you only need to include the static library file in the project and reference the functions or variables in the static library in the code. During compilation, the compiler links the code and data of the static library file into the executable program, generating an executable program that contains the static library code and data. At runtime, the executable program does not need to reference the static library file, because the code and data of the static library have been linked into the executable program.

When using a dynamic library, you need to include the dynamic library (import library) file in the project and reference the functions or variables in the dynamic library in the code. At compile time, the compiler does not link the code and data of the dynamic library file into the executable program, but dynamically links the dynamic library file at runtime.

1. The sizes of executable files are different.
A statically linked executable file is much larger than a dynamically linked executable file, because it copies the code it needs to use from the binary file, while dynamic linking only copies it. Some relocation and symbol table information. The static library is simple and runs faster; however, the generated exe file is larger and is inconvenient to upgrade and maintain. Dynamic libraries are relatively cumbersome to use, but modularization is easy.

2. The occupied disk size is different.
If there are multiple executable files, the code of the same function in the static library will be copied multiple times, while the dynamic library only has one copy, so the disk space occupied by the static library is relatively larger than that of the dynamic library. The library needs to be large.

3. Scalability and compatibility are different.
If the implementation of a function in the static library changes, the executable file must be recompiled. For executable files generated by dynamic linking, you only need to update the dynamic library itself, no need Recompile the executable file. Because of this, programs that use dynamic libraries are easy to upgrade and deploy.

4. Different dependencies:
Statically linked executable files do not need to rely on other content to run, while dynamically linked executable files must rely on the existence of dynamic libraries. So it's not surprising if you are prompted that a certain dynamic library does not exist when installing some software.

Even so, there are generally a large number of public libraries in the system, so there is no problem in using dynamic libraries.

5. Different complexity.
Relatively speaking, the processing of dynamic libraries is more complicated than static libraries. For example, how to confirm the address at runtime? How do multiple processes share a dynamic library? Of course, as the caller, we don't need to pay attention. In addition, the management of dynamic library versions is also a technical activity. This is also beyond the scope of this article.

6. The loading speed is different.
Since the static library is linked with the executable file when it is linked, and the dynamic library is linked when it is loaded or run, therefore, for the same program, the static link loads faster than the dynamic link. So choosing a static library or a dynamic library is a consideration of space and time. But generally speaking, it is worth sacrificing this performance in exchange for program space savings and deployment flexibility. Coupled with the locality principle, the performance sacrificed is not much. (The principle of locality means that when the CPU accesses memory, whether it is accessing instructions or data, the accessed storage units tend to be gathered in a smaller continuous area.)

lx is very good, very good, the difference between header files and library files, the difference between dynamic libraries and static libraries, the generation of dynamic and static libraries_the difference between header files and library files

3.3.4.2 Both dynamic libraries and static libraries have .lib files. What is the difference?

1. This problem has troubled me for a long time. At first, I thought that dynamic libraries do not have .lib files. In fact, dynamic libraries also have .lib files, but they are different from the .lib files of static libraries. The library directory set in vs2019 is the .lib library, which is also called an import library in dynamic libraries. In fact, we are using a third-party dynamic library, and there is no third-party dynamic library here at all.

2. In Windows, a dynamic library file usually contains two files, one is the import library file (Import Library), with the extension ".lib", and the other is the dynamic link library file (Dynamic Link Library), with the extension ".lib" .dll".
An import library file (.lib) is a binary file that contains a symbol table that allows the compiler to resolve references to functions and variables at compile time. The import library file contains the symbol information of all exported functions in the dynamic link library, as well as the entry address of the function and other information. When compiling, the compiler links the import library files into the executable file so that the dynamic link library is loaded at runtime.
A dynamic link library file (.dll) is a binary file containing executable code and data that can be loaded into memory at runtime and shared by multiple processes. The dynamic link library contains a set of exported functions that can be called by other programs. When a program calls a function in a dynamic link library, the operating system will resolve the entry address of the function and transfer control to the code of the function.
In summary, the import library file (.lib) and the dynamic link library file (.dll) are the two components of the dynamic library, and they are usually used together to correctly link and load the dynamic library at compile time and runtime.

3. Lib in the static library: This LIB contains the function code itself (that is, including the index of the function, including the implementation). The code is directly added to the program during compilation. Lib in the dynamic library: This LIB contains the DLL file where the function is located
. And the function location information (index) in the file, the function implementation code is provided by the DLL loaded in the process space at runtime
. In short, lib is used during compilation, and dll is used at runtime. If you want to compile the source code, you only need lib; if you want to run a dynamically linked program, you only need dll.

4. Why does the dynamic library still have a .lib file? That is, whether it is a static link library or a dynamic link library, there is a lib file in the end, so what is the difference between the two? In fact, the two are completely different things.
The size of Library.lib in the static library is 190KB, and the size of Library.lib in the dynamic library is 3KB. The lib file corresponding to the static library is called a static library, and the lib file corresponding to the dynamic library is called [import library]. In fact, the static library itself contains the actual execution code, symbol table, etc., and for the import library, the actual execution code is located in the dynamic library. The import library only contains the address symbol table, etc. to ensure that the program finds the corresponding function. Some basic address information.

5. In Linux, a dynamic library file usually contains a shared object file (Shared Object) with the extension ".so". The dynamic library file in Linux only has so, but not .a. Windows is different from Linux. In Windows, a dynamic library file usually contains two files, one is the Import Library file (Import Library), with the extension ".lib", and the other is the Dynamic Link Library file (Dynamic Link Library), with the extension Named ".dll".

6. When we use the gdal program in vs2019, we need to set the library directory in the project properties. There are two situations. 1. If we are using a dynamic library, the library directory here is the location of the .lib import library. Finally, we need to put the .dll dynamic library file into the same level directory as exe. 2. If it is a static library, the library directory here is the location of the .lib static library, and in the end there is no need for a .dll file.
Insert image description here

Discuss in detail the difference between static libraries and dynamic libraries_The difference between dynamic libraries and static libraries_Kernel Basecamp's Blog-CSDN Blog

3.3.4.3 Differences in file formats between dynamic libraries and static libraries on window and Linux systems

1. In windows
(1) static library: header file (.h file) + static library file (.lib file), it consists of these two types of files;
(2) dynamic library: header file (.h file) + static library File (also called import library, .lib file) + dynamic library file (.dll file), composed of these three types of files;
2. In Linux
(1) static library: header file (.h file) + static library file ( .a file), consisting of these two types of files;
(2) Dynamic library: header file (.h file) + dynamic library file (.so file), consisting of these two types of files;

3.3.4.4 Static library features:

The linking of the static library to the function library is completed during compilation.
The program has nothing to do with the function library when it is running, making it easy to transplant.
It wastes space and resources because all related object files and involved function libraries are linked into one executable file.

3.3.4.5 Summary of dynamic library features:

Dynamic libraries defer the link loading of some library functions until the program is running.
Resource sharing between processes can be achieved. (So ​​dynamic libraries are also called shared libraries)
Make upgrading some programs simple.
It is even possible to truly achieve link loading completely controlled by the programmer in the program code (explicit call).

3.4 Production of dynamic libraries and static libraries in windows and linux environments

1. lx is very good, very good: how to generate dynamic libraries and static libraries, the difference between lib and dll, detailed explanation of generation and use
2. lx is very good, very good: the difference between dynamic libraries and static libraries, in windows and linux environments Production and usage_windows linux dynamic library

3.4.1 Static library

The static library is suffixed with .a (archive) in Linux. Its function is to copy the required content from the static library file to the final executable file when linking to generate an executable file.

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

Production of static libraries in Linux systems:

//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 指定库名
测试目标文件生成后,静态库删掉,程序照样可以运行。

Note: The naming rule for static library files and dynamic library files is libxxxx.a/libxxxx.so. When linking, just use lxxxx instead of libxxxx.so.

Insert image description here

3.4.2 Dynamic library

The dynamic library in Linux has the suffix .so (shared object). It does not copy all the required binary codes to the executable file when linking, but copies some relocation and symbol table information, which is needed when the program is running. Then obtain it from the dynamic library through the symbol table.

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

Insert image description here

3.5 How to use third-party libraries

In addition to introducing compiled libraries into projects, some people also introduce open source software in the form of source code, such as GCC, SDL, WxWights, and QT. If the compilation of the third-party library itself is not complicated and the original code is very simple, this is better.
But libraries like Boost.Thread don't work. It needs to be compiled into a dynamic library, and static references will cause problems.

There are three ways to introduce third-party libraries:
(1) Source code: The source file (.cpp) and header file (.h) that reference the project must be included in the project. This method will cause the project to be relatively large. Reference 2 something.
(2) Dynamic library: You only need to include the dll file that references the project. The header file and lib library file of the referenced project are optional and are usually included. Quote 3 things.
(3) Static library: It only needs to include the lib file and header file compiled by the reference project. The project will look cleaner and simpler, citing two things.

(1) Prepare data: Compile the source code of the third-party library into a dynamic library or static library (we can find the compiled dynamic library or static library to avoid compilation errors by ourselves). This step is the most fundamental. Whether in Linux or Windows, you cannot use the compiled third-party libraries without downloading them.

(2) Configuration environment: Configure it into your project, which can be vs, clion, or notepad. Import the a file or lib file and header file for your project.
How to connect C++ projects on Windows and Linux platforms to third-party dependent libraries_libopencv_world.so.4.5_Yu Gongbu Yishan's blog-CSDN blog
(3) Programming: Reference the header file and call the third-party library function Programming: Programming.
(4) Compilation: Package into an executable program: Cmake package and compile, or g++ compile.
(5) Run: Run the executable program: If it is a dynamic library, you need to place the .dll file or .so file in the same directory as .exe or .out. This step is not necessary for static libraries.
Insert image description here

lx very good very good General usage of third-party libraries in C++ (libxl library as an example)

3.5.1 Introduction of third-party libraries under windows

Introducing third-party libraries under Windows means introducing dynamic libraries or static libraries. Source code is also acceptable, but source code is generally not used.
There are two ways to introduce third-party libraries to windows: one is to use Cmakelist file organization, similar to maven; the other is to configure it directly in software such as vs, clion.

3.5.1.1 Introduction of static libraries under windows

In Windows, the method of using static libraries to import third-party libraries is to configure the two files: .h header file and .lib file.
(1) In the vc++ of the project properties in vs2019, include the directory configuration header file directory and the library directory configuration .lib directory.
Insert image description here
(2) Configure the static file name to be imported in the input additional dependencies.
Insert image description here

3.5.1.1 Introducing dynamic libraries under windows

In Windows, the method of using dynamic libraries to import third-party libraries is to configure the three files: .h header file, .lib file and .dll.
(1) In the vc++ of the project properties in vs2019, include the directory configuration header file directory and the library directory configuration .lib directory.

(2) Configure the static file name to be imported (also called an import library) in the input additional dependencies.
(3) On the basis of the static library, put the .dll dynamic library file into the same directory as .exe.

3.5.2 Introduction of third-party libraries under Linux

First of all, make it clear that introducing third-party libraries under Linux means introducing dynamic libraries or static libraries.
(1) In Linux, the method of using static libraries to import third-party libraries is to configure the two files, .h header file and .a file.
(2) The method of using dynamic libraries in Linux to import third-party libraries is to configure the two files, .h header file and .so file, and then put the .so dynamic library file into the same level directory of the program.
(3) There are two ways to introduce third-party libraries in Linux: one is to use makefile files; the other is to use Cmakelist file organization.

3.5.3 Several small cases of citing third-party libraries

具体案例可以看第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.5.4 lib库的配置有两种方式

一种是在程序代码中进行配置(不用)
一种是Cmakelist或者vs等软件按钮中进行配置;
Windows中C++动态库和静态库的使用方法和区别_使用静态库需要头文件吗_QuattroA8的博客-CSDN博客

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

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

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

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

4.1 windows系统下导入第3方库

4.1.1 Third-party library installation process in VS

A total of 4 steps:
1. Add the header file directory include
2. Add the static library directory lib library
3. Add additional dependencies, that is, specific static library files
4. Place the dynamic library files in the same directory as .exe

Insert image description here
Insert image description here
Insert image description here

However, when I usually use software such as Visual Studio, I do not come into contact with the compilation process, because VS is a highly integrated development environment (IDE, Integrated Development Environment) that integrates a code editor, compiler, debugger and graphical user interface. All of the above The program compilation and linking processes are all carried out using one-step build.

[1] lxverygoodverygoodHow to call dynamic and static libraries lib and dllThe difference, generation and use of detailed explanations
[2] lxverygoodverygoodGeneral use of third-party libraries in C++ (libxl library as an example)
[3 ] C++ basics - How to introduce third-party static libraries, dynamic libraries or custom libraries_How to import third-party libraries in c++
[4] Introduction to the installation and use of C++ third-party log library Glog

4.1.2 Third-party library installation process in Clion

[1] How to use CMake to import third-party libraries in CLion_Detailed methods of introducing third-party libraries in CLion

The following is written very clearly. You must first compile the source code into a dynamic library or a static library and then import it
[2] C++ loading static libraries and dynamic libraries in CLion - CSDN Blog

[3] lx is very good, very good CMakeLists.txt Concise syntax tutorial CSDN blog

4.1.3 Third-party library installation process in vscode

It seems that vscode needs to configure a json file when calling a third-party library.
How to use C++ language to call third-party libraries in VScode - Zhihu

4.1.4 CmakeList

CmakeList.txt is a file executed by Cmake software. Third-party libraries can be directly introduced through CmakeList. Adding a third-party library mainly involves three commands: 1 is to add .h header files; 2 is to add
library
files;
3 is to add dynamics Library (if you add a dynamic library)

#设置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 needs to be placed after add_executable to indicate the connected library. This interface is officially recommended, but link_libraries is not recommended. Link_libraries needs to be placed before add_executable.

lx is very good, very good CMakeLists.txt Concise syntax tutorial CSDN blog

CMakeLists.txt super fool step-by-step tutorial (with example source code)_Yngz_Miao-DevPress official community

cmake adds header file directory and links dynamic and static libraries - CSDN Blog

A detailed introduction to CMake from scratch_bilibili_bilibili

How to use CMake to import third-party libraries in CLion_Detailed methods of introducing third-party libraries in CLion

CMake introduces third-party libraries_cmake adds third-party libraries_ccsu_zzh's blog-CSDN blog

cmake introduces third-party libraries (header file directory, library directory, library files)_cmakelist adds third-party libraries_A Midsummer Night's Dream~'s blog-CSDN blog

CMake introduces third-party libraries_cmake adds third-party libraries_ccsu_zzh's blog-CSDN blog

4.1.4.1 Add dynamic library to 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 Add static library to Cmakelist

You only need to remove the last step of the above dynamic library adding process "copy GDAL_DLL to the execution project directory".

4.2 Import third-party libraries under Linux system

4.2.1 CmakeList

It's the same as under windows, because CmakeList is designed to be cross-platform.

4.2.2 makefile

[1] Video lessons of the King's Way Training Camp
[2] Makefile perfect tutorial_makefile tutorial_WittXie's blog-CSDN blog
[3] Makefile basic tutorial_makefile novice tutorial-C document resources-CSDN library

5 Install gdal library

5.1 Clion installs the GDAL library

5.1 Successful installation

Follow the following process to install gdal. The bitter experience of using gdal in clion_gdal clion configuration_jayce_tang's blog-CSDN blog , but an error will still be reported.
Insert image description here
After that, Baidu found that this error was reported because it was indeed a dll dynamic link library: the libgdal.dll file Place it in the same directory as exe and execute successfully.
Insert image description here

CLion program compilation error 0xC0000135_How to solve the link problem when compiling clion_Cliven_'s blog-CSDN blog

Reference:
[1] The bitter journey of using gdal in clion_gdal clion configuration_jayce_tang's blog-CSDN blog
[2] VS2017 compilation and configuration GDAL - super detailed, suitable for beginners! ! ! _vs compile gdal_Chang'anyou's blog-CSDN blog

5.1.2 Core points

Online tutorials are generally based on VS. In fact, the previous compilation should be the same whether it is VS or Clion.
We can't compile it ourselves, so we use files compiled by others.
Then configure it in Clion.

5.2 Install gdal library in VS software environment

I successfully executed the following program on vs2019. The installation process is based on this blog. The only mistake is that the lib library does not need to be configured in the environment variable. Instead, the .dll library in the bin directory must be placed in the generated .exe file. directory at the same level, very good! Success! ! !
Detailed use cases of GDAL under C++ (including project configuration, reading tif as cv::Mat, and saving Mat as tif)_c++ gdal_Wanli Pengcheng Zhuanzhi's Blog-CSDN Blog

5.2.1 Use the configured environment to read raster information (executed successfully)

// 获取栅格信息
#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 Use the configured environment to read the shp file (executed successfully)

// 这个文件是读取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] Compile, install and use gdal-2.4.2_gdal2.4 installation under windows_The Grasshopper in the Grass' blog-CSDN blog
[1] GDAL-3.4.0 library C++ version compilation_Compiled gdal_lufengok's blog-CSDN blog

5.3 Install gdal library in linux environment

5.4 Several tutorial cases to try to implement

【1】c++ GDAL reads shapefile file_gdal opens shapefile file_Chaoying.'s blog-CSDN blog

【2】(433 messages) Combining C++ and GDAL to read shapefile (shp) files_weixin_33675507's blog-CSDN blog

// 在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++ calls GDAL to read raster data_c++ calls gdal_Sanqiansi's blog-CSDN blog

[4] GDAL C++ development summary (1) Obtain the coordinates of any point in the image, and perform coordinate conversion on the point coordinates, such as converting projected coordinates to geographical coordinates, UTM to 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 Install third-party libraries

6.1 vs2019 install opencv library

Installing the opencv library is nothing more than using existing programs directly, or using packages packaged by others.

Refer to this document, it is too simple, all versions have it:
2022 New version c++ simple operation tutorial for installing opencv library_Jilu Di1895's blog-CSDN blog

1. Mainly refer to the following two documents for implementation:
opencv installation and configuration vs2019_opencv vs2019_Ping Yangzhu's blog-CSDN
blogVS2019 OpenCV installation and configuration tutorial_vs2019 installation opencv_XHR-imaginary blog-CSDN blog

2. The opencv package installed above does not have the xfeature2d.hpp module. This is an extension library of opencv. This extension library is needed when using the SOUR algorithm. For the installation of the extension library, see the link below: OpenCV does not have xfeatures2d
solution_opencv_ Quiet 55668-DevPress official community

3. According to the above steps, it is quite troublesome. In step 2, opencv_xfeatures2d453.lib and other files are missing, and it cannot run when running the surf algorithm. Then I found the compiled library below. The opencv library contains two libraries, one is the opencv library and the other is the opencv_contrib library, which is equivalent to an expansion library of the basic opencv.
Dynamic library resources compiled by opencv453+vs2019-CSDN Library

Installing all packages is the same, just 3 steps:
1. Find the package of the third-party library;
2. Configure the header file directory and static library file directory in vs;
3. Place the dynamic library .dll at the same time as the executable program .exe. directory or environment variables.

// 测试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;
}

6.2 C++ installation eigen - successful

C++ installation of eigen - simple - successful
two steps: download and import

7 Compiling and packaging c++ executable programs in linux

Note: Whether it is Windows or Linux, the main focus is on three things, header files, static libraries, and dynamic libraries. Among them, the static library is sometimes needed and sometimes not, and it has not been clarified yet. Just download these 3 folders and specify g++ directly when compiling.
There is no need to specify g++ in vs2019. The essence is that you specify it in the project properties, and it is also specified;
in Linux, g++ -I and -L are specified.

7.1 Program input parameters

In C++, you can use the parameters of the main function to receive external input parameters. Specifically, the main function can have two parameters: argc and argv.

argc represents the number of parameters, which is an integer type variable. argv is a pointer to an array of character pointers that stores the value of each argument. The first parameter is the name of the program, starting with argv[1] are the actual parameters passed to the program.
(1) Procedure:

#include <iostream>
using namespace std;

int main(int argc, char *argv[]) {
    
    
    cout << "The program name is: " << argv[0] << endl;
    cout << "The number of arguments is: " << argc << endl;
    for(int i = 1; i < argc; i++) {
    
    
        cout << "Argument " << i << " is: " << argv[i] << endl;
    }
    return 0;
}

(2) Output:

The program name is: ./test
The number of arguments is: 4
Argument 1 is: arg1
Argument 2 is: arg2
Argument 3 is: arg3

7.2 Prerequisite knowledge

7.2.1 Compilation requires header files and library files

7.2.2 LD_LIBRARY_PATH environment variable

The LD_LIBRARY_PATH environment variable is set. When the program uses a third-party library when compiling and executing, it will automatically look for it in the environment variable.

1输出环境变量:echo $LD_LIBRARY_PATH
2设置环境变量:export LD_LIBRARY_PATH=/path/to/gdal/lib:$LD_LIBRARY_PATH
3将动态库复制到系统默认动态库环境变量中:sudo cp /path/to/gdal/lib/libgdal.so.* /usr/lib/
4防止编译时找不到动态库,可以在编译时指定动态库位置:编译程序时使用-Wl,-rpath选项来指定运行时库文件的搜索路径。g++ -o your_program your_program.cpp -I/path/to/gdal/include -Wl,-rpath,/path/to/gdal/lib -L/path/to/gdal/lib -lgdal
5查看可执行程序依赖的库文件列表,ldd命令会递归地查找所有依赖的库文件,并显示它们的路径和版本信息。ldd your_program

/usr/lib/It is a directory in the Linux system used to store shared library files (also called dynamic link library files). A shared library file is a reusable code library that can be shared among multiple programs, thereby reducing the usage of system resources and the footprint of the program.

In Linux systems, shared library files usually .sohave extensions such as libgdal.so. These files are usually stored in /usr/lib/the directory because this is one of the system's default shared library file paths. When a program needs to use a shared library file, the system will search for the corresponding file in the default shared library file path.

Note that /usr/lib/directories are typically writable only by administrator users, so if you need to copy shared library files into this directory, you will need administrator rights.
Insert image description here

7.2.3 g++ compile c++ program commands


1 g++ -o executable_name source_file.cpp  // 编译普通文件
2 g++ -o your_program your_program.cpp -lgdal  // 编译带gdal包的文件,默认从环境变量找头文件和库文件。
3 g++ -o your_program your_program.cpp -I/path/to/gdal/include -L/path/to/gdal/lib -lgdal  // -I选项用于指定头文件路径,不涉及库文件,-L选项用于指定库文件所在的目录,-l选项用于指定库文件名。-lgdal指令会去找libgdal.a或者libgdal.so,-L和-l不管是动态库还是静态库都一样。-l选项后面跟的是库文件的名称,不需要包含文件扩展名。
4 g++ -o your_program your_program.cpp -I/path/to/gdal/include -Wl,-rpath,/path/to/gdal/lib -L/path/to/gdal/lib -lgdal  // 防止运行时找不到动态库文件,编译程序时使用-Wl,-rpath选项来指定运行时库文件的搜索路径。
 

(1) The -L and -l options are used to specify the library file path and library file name, and can be used to link static libraries and dynamic libraries. The -I option is used to specify the header file path and does not involve library files.

Both static and dynamic libraries can be linked using the -L and -l options. The -L option is used to specify the directory where the library file is located, and the -l option is used to specify the library file name. For example, assuming we have a static library file named libfoo.a and a dynamic library file named libbar.so, we can link using the following command:

Static library link: g++ main.cpp -L/path/to/lib -lfoo
Dynamic library link: g++ main.cpp -L/path/to/lib -lbar
Among them, -L/path/to/lib specifies the library file directory, -lfoo and -lbar specify the names of static library files and dynamic library files respectively. It should be noted that the names of static library files usually end with .a, while the names of dynamic library files usually end with .so.

(2) g++ -o your_program your_program.cpp -std=c++11 -I/path/to/gdal/include -L/path/to/gdal/lib -lgdal, does -lgdal here point to a dynamic library or Static library?
-lgdal points to the dynamic library file of the GDAL library, because in the Linux system, the naming rule for dynamic library files is lib*.so, while the naming rule for static library files is lib*.a. Therefore, if -lgdal points to a static library file, it should be -lgdal.a, not -lgdal.

It should be noted that if there are both static libraries and dynamic library files, -lgdal will link the dynamic library files by default.

7.2.4 Compiling dynamic libraries and static libraries

(1) Windows version:
Compiling the gdal dynamic library in the Windows version will generate a .lib file, but this is actually different from the .lib file of the actually compiled static library. The .lib file generated by compiling the dynamic library is an import library.

(2) Linux version:
When compiling a dynamic library, a static library file (.a file) is usually also generated at the same time. This is because although static libraries and dynamic libraries are used in different ways, their source code and compilation process are the same, so it is very common to generate static libraries and dynamic libraries at the same time during the compilation process. The .a file generated here is a real static library file, but when using a dynamic library, the .a static library file will not be used.

If you only need to use dynamic libraries, you can ignore static library files. If you need to use a static library, you can link the static library file into your application. When using a static library, you need to specify the static library file name when compiling and linking, otherwise the dynamic library file will be loaded by default, for example:

g++ -o myapp myapp.cpp -L/path/to/lib -lgdal_static
// 其中,-L选项指定静态库文件所在的路径,-lgdal_static指定要链接的静态库文件名。
//需要注意的是,如果您的动态库和静态库同时存在,且它们的文件名相同,那么在链接时需要使用不同的选项来指定使用动态库还是静态库。
//例如,使用动态库时需要使用-lgdal,而使用静态库时需要使用-lgdal_static。

7.2.5 The export command imports environment variables

//  在Linux中,导入第三方库时需要使用export命令来设置环境变量,以便让系统能够找到库文件。具体命令如下:
export LD_LIBRARY_PATH=/path/to/library:$LD_LIBRARY_PATH

Among them, /path/to/library is the path where the third-party library file is located, and $LD_LIBRARY_PATH is the system default library file search path. By adding /path/to/library to the LD_LIBRARY_PATH environment variable, the system can find third-party libraries when searching for library files.

It should be noted that the LD_LIBRARY_PATH environment variable only takes effect in the current terminal window. If you need to automatically set the LD_LIBRARY_PATH environment variable in other terminal windows or when the system starts, you can add the above command to the .bashrc file. For example:

echo 'export LD_LIBRARY_PATH=/path/to/library:$LD_LIBRARY_PATH' >> ~/.bashrc

Insert image description here

7.3 Compile c++ program

7.3.1 Individual programs without 3rd party packages

// linux2GdalReadShp.cpp
#include <iostream>
#include <string>

int main(int argc, char* argv[]) {
    
    
    if (argc != 2) {
    
    
        std::cout << "Usage: " << argv[0] << " name " << std::endl;
        return 1;
    }

    std::cout << " hello: " << argv[1] << std::endl;

    return 0;
}

Compilation and test execution were successful

g++ -o executable_name source_file.cpp

7.3.2 Single program with 3rd party packages (gdal)

// 这个函数验证读取shp文件是否可行
#include "ogrsf_frmts.h"
#include <iostream>
using namespace std;

int main(int argc, char* argv[])
{
    
    
    GDALAllRegister();
    GDALDataset* poDS;
    const char* gdal_version = GDALVersionInfo("RELEASE_NAME");
    std::cout << "GDAL version: " << gdal_version << std::endl;
    CPLSetConfigOption("SHAPE_ENCODING", "");  //解决中文乱码问题
    //读取shp文件
    poDS = (GDALDataset*)GDALOpenEx(argv[1], 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;
}
g++ -o your_program your_program.cpp -std=c++11 -I/path/to/gdal/include -L/path/to/gdal/lib -lgdal
// -o可以放了后面
g++ your_program.cpp -std=c++11 -I/path/to/gdal/include -L/path/to/gdal/lib -lgdal -o your_program
// 实战中在linux中执行成功的
,gdal库的头文件和库文件已经放到了下面两个文件夹中了,-std=c++11可以没有:
g++ linux2GdalReadShp.cpp -std=c++11 -I/usr/local/include -L/usr/local/lib -lgdal -o linux2GdalReadShp

7.3.3 Single program with 3rd party packages (opencv)

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;


int main(int argc, char** argv)
{
    
    
    // 输出OpenCV版本
    cout << "OpenCV version : " << CV_VERSION << endl;
    cout << "Usage: " << argv[0] << " <image_path>" << endl;
    // 检查命令行参数
    if (argc != 2)
    {
    
    
        cout << "argc is wrong!!!" << endl;
        return -1;
    }

    // 读取图像
    Mat image = imread(argv[1], IMREAD_COLOR);
    //Mat image = imread("E:/data/1putongImageMatch/shanghai2GaoQing.png", IMREAD_COLOR);
    // 判断图像是否读取成功
    if (image.empty())
    {
    
    
        cout << "Could not open or find the image" << endl;
        return -1;
    }
    else
    {
    
    
        cout << "read the image succeed!!!" << endl;
    }

    // 转换为灰度图像
    Mat gray_image;
    cvtColor(image, gray_image, COLOR_BGR2GRAY);

    // 保存灰度图像
    string output_path =  "./gray.jpg";
    imwrite(output_path, gray_image);

    return 0;
}
// 使用下面的命令成功编译运行
g++ linux3OpencvSaveImage.cpp -I/usr/local/opencv3.0/include -I/usr/local/opencv3.0/include/opencv2.0 -L/usr/local/opencv3.0/lib -lopencv_core -lopencv_imgcodecs -lopencv_imgproc -lopencv_highgui -o linux3OpencvSaveImage

7.3.4 Multiple programs with 3rd party packages (opencv)

// linux4readimg.cpp
#include "linux4readimg.h"

Mat imageread(string imgpath) {
    
    

	Mat image = imread(imgpath, IMREAD_COLOR);
	cout <<"width and height:" <<image.cols << "  " << image.rows<<endl;
	return image;
}
// linux4readimg.h
#pragma once
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;

Mat imageread(string imgpath);
//  linux4OpencvImg.cpp
// 测试4,使用两个文件
#include <linux4readimg.h>
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;


int main(int argc, char** argv)
{
    
    
    // 输出OpenCV版本
    cout << "OpenCV version : " << CV_VERSION << endl;
    cout << "Usage: " << argv[0] << " <image_path>" << endl;
    // 检查命令行参数
    if (argc != 2)
    {
    
    
        cout << "argc is wrong!!!" << endl;
        return -1;
    }

   
    Mat image = imageread(argv[1]);
    //Mat image = imageread("E:/data/1putongImageMatch/shanghai2GaoQing.png");
    // 判断图像是否读取成功
    if (image.empty())
    {
    
    
        cout << "Could not open or find the image" << endl;
        return -1;
    }
    else
    {
    
    
        cout << "read the image succeed!!!" << endl;
    }

    return 0;
}

// 使用下面的命令成功编译运行,项目共3个文件,2个.cpp,1个.h
g++ linux4OpencvImg.cpp linux4readimg.cpp -I/usr/local/opencv3.0/include -I/usr/local/opencv3.0/include/opencv2.0 -L/usr/local/opencv3.0/lib -lopencv_core -lopencv_imgcodecs -lopencv_imgproc -lopencv_highgui -o linux4OpencvImg
// main.cpp和helper.cpp是源文件的名称,helper.h会被自动包含进去,不用再特殊指明位置了

7.3.5 Programs containing both opencv and gdal libraries

// 使用opencv3版本的库成功执行
/usr/local/gcc-8.3.0/bin/g++ -o linux5TemplateMatch -std=c++11 linux5TemplateMatch.cpp GDALread.cpp GCPTransformer.cpp  TemplateMatch.cpp -I/usr/local/opencv3.0/include -I/usr/local/opencv3.0/include/opencv2.0 -I/usr/local/include  -L/usr/local/opencv3.0/lib -lopencv_core -lopencv_imgcodecs -lopencv_imgproc -lopencv_highgui -L/usr/local/lib -lgdal -Wl,-rpath=/usr/local/opencv3.0/lib

Note: Multiple versions of the library may conflict

// 当linux系统中有多个库的时候,/usr/local/lib下面有opencv2.0版本的库的时候,如果把-L/usr/local/lib放在-L/usr/local/opencv3.0/lib前面,会导致库的依赖2.0版本的库和3.0版本的库混乱,执行出错,所以顺序很重要
// opencv2是一个文件夹,在opencv3.0版本和opencv2.0版本中都存在,opencv2和opencv2.0不一样。
// 下面的编译可能会成功,也可能失败,即使编译成功,执行也会错误。
/usr/local/gcc-8.3.0/bin/g++ -o linux5TemplateMatch -std=c++11 linux5TemplateMatch.cpp GDALread.cpp GCPTransformer.cpp  TemplateMatch.cpp ......

7.3.6 Programs containing both opencv and gdal libraries use OpenMP acceleration

This will use the GCC compiler and enable OpenMP support using the "-fopenmp" option.

Run the executable file and you should see that the code blocks are executed in parallel by multiple threads, thus speeding up the execution of the program.

Note that the effectiveness of OpenMP depends on the structure of the code and the computational load. In some cases, using OpenMP may cause performance degradation, so you will need to test and optimize for the best performance.

Although OpenMP is not native to C++, many C++ compilers support OpenMP and can use OpenMP to accelerate the execution of C++ programs. For example, compilers such as GCC, Clang, and Microsoft Visual C++ all support OpenMP.

gcc -fopenmp your_code.c -o your_executable
g++ -o myprogram myprogram.cpp
// 自己的程序使用了下面的编译命令,但是运行时候报错segmentation fault(core dumped)
// 内存超了,所以需要减少内存,在命令中使用了减少进程的设置export OMP_NUM_THREADS=4   # 设置线程数为4,或者也可以在代码中进行设置omp_set_num_threads(4);确实成倍加快了速度
// 线程数最好不要超过cpu核数 
/usr/local/gcc-8.3.0/bin/g++ -fopenmp -o linux6TemplateMatchMP -std=c++11 linux6TemplateMatchMP.cpp GDALread.cpp GCPTransformer.cpp  TemplateMatch.cpp ......

8 Summary

(1) Clarify the C++ program execution process: 5 steps: Prepare the files required for programming, set up the environment, programming, compilation, and execution (2) Clarify
what the compilation software is:
(3) Clarify the compilation process into 4 Steps:
(4) Clarify what dynamic libraries and static libraries are:
(5) Clarify how to use third-party libraries in a project. Third-party libraries need to be considered in the 4 steps of C++ program execution: Preparation required for programming When making files, you must consider whether the third-party library is source code or a compiled file (if it is source code, you need to compile the third-party library first). When building the environment, you need to configure the third-party library. When programming, reference the third-party library header file and use it. When compiling third-party library functions, consider how to package them, and when executing, consider whether to use the .dll file of the dynamic library of a third-party library.
(6) Clarify the introduction of third-party libraries (guide packages): it means introducing dynamic libraries or static libraries, or source code. Just choose one of these three methods, but generally you do not need to directly use the source code of the third-party library. The source code of the third-party library will also be programmed into a dynamic library or a static library first.
(7) To use a static library in Windows to import a third-party library, you need to configure the two files: the .h header file and the .lib file.
(8) The method of using dynamic libraries in Windows to import third-party libraries is to configure the three files: header file, .lib file and .dll, and then put the .dll dynamic library file into .exe on the basis of the static library. Directory at the same level (the exe is in different folders in debug and release modes).
(9) In Linux, using the static library method to import a third-party library is to configure the two files, the .h header file and the .a file.
(10) The method of using dynamic libraries in Linux to import third-party libraries is to configure the two files, .h header file and .a file, and then put the .so dynamic library file into the same file as .out based on the static library. level directory.
(11) Windows and Linux use source code to import third-party libraries, just put them directly in the project directory. Generally, source code is not used, but the source code is compiled into a dynamic library or static library in advance, and then the dynamic library or static library is used. method to import third-party libraries.
(12) Windows and Linux import third-party libraries in the same way: import dynamic libraries or static libraries;
(13) Windows introduces third-party libraries in two ways: one is to use Cmakelist file organization, similar to maven; the other is to use vs Configure directly in software such as , clion and so on.
(14) There are two ways to introduce third-party libraries in Linux: one is to use makefile files; the other is to use Cmakelist file organization.
(15) Under Windows, the .lib in the dynamic library file and the .lib in the static library file are different.

(16) Clarify how to use third-party libraries in different integrated software:

Guess you like

Origin blog.csdn.net/xiaotiig/article/details/129520328