Linux编程的第三方库引用------gcc、pkg-config与CMake一文讲解

2023-05-16

众所周知 linux 下库文件编译三部曲 config make makeinstall

configure过程中可能会遇到无法找到某些头文件和动态库;原因有两个:

   (1)系统没有这些头文件和动态库。(locate XXXX.h/so 未找到)
   (2)已经安装相关的头文件和动态库。但未将头文件和动态库拷贝到标准路径下。

config 时如果使用第三方库如何呢
接下来我们以一个很简单的使用opencv库读取并显示图片的程序做示例。

//文件路径
.
├── cat.jpeg
└── test.cpp

2 directories, 8 files
//test.cpp 读取图片
#include <stdio.h>
#include <opencv2/opencv.hpp>
using namespace cv;
int main(int argc, char** argv )
{
    if ( argc != 2 )
    {
        printf("usage: DisplayImage.out <Image_Path>\n");
        return -1;
    }
    Mat image;
    image = imread( argv[1], 1 );
    if ( !image.data )
    {
        printf("No image data \n");
        return -1;
    }
    namedWindow("Display Image", WINDOW_AUTOSIZE );
    imshow("Display Image", image);
    waitKey(0);
    return 0;
}

Linux下gcc 链接第三方库

如果使用gcc 编译器 那么使用第三方链接库是这样子的

#!/bin/bash
g++ -o opencvtest test.cpp \
-I /home/ywz/WorkSpace/install/include/opencv \
-I /home/ywz/WorkSpace/install/include \
-L /home/ywz/WorkSpace/install/lib -lopencv_core -lopencv_highgui -lopencv_imgproc -lopencv_imgcodecs

编译后生成可执行文件opencvtest

如果 一个大型的工程 有很多的第三方链接库 那么我们使用gcc 链接库要一个一个的设置链接路径 是很繁琐且容易出错的
有没有更简单的方法呢
这里就可以使用pkg-config工具来管理已安装的链接库了

linux下工具 pkg-config 链接第三方库

pkg-config 简介

man pkg-config 这部分介绍是机器翻译的 可以对比原文看。
名称
PKG - 配置 -返回的元信息有关安装的库
描述
该PKG - 配置程序是用来检索有关系统安装的库信息。它通常用于编译和链接一个或多个库。这是Makefile中的典型使用场景:
Here is a typical usage scenario in a Makefile:

program: program.c

···
cc program.c 'pkg-config --cflags --libs gnomeui'
···

pkg-config retrieves information about packages from special metadata files. These files are named after the package, with the extension .pc. By default, pkg-config looks in the directory prefix/lib/pkgconfig for these files; it will also look in the colon-separated (on Windows, semicolon-separated) list of directories specified by the PKG_CONFIG_PATH environment variable.
The package name specified on the pkg-config command line is defined to be the name of the metadata file, minus the .pc extension. If a library can install multiple versions simultaneously, it must give each version its own name (for example, GTK 1.2 might have the package name “gtk+” while GTK 2.0 has “gtk±2.0”).
pkg - config从特殊的元数据文件中检索有关软件包的信息。这些文件以软件包名称命名,扩展名为 .pc。默认情况下, pkg - config在目录prefix / lib / pkgconfig中查找这些文件;它还将在由PKG_CONFIG_PATH环境变量指定的目录的冒号分隔(在Windows中,用分号分隔)列表中查找。
在pkg - config命令行上指定的软件包名称定义为元数据文件的名称,减去.pc扩展名。如果一个库可以同时安装多个版本,则它必须为每个版本指定自己的名称(例如,GTK 1.2的程序包名称为“ gtk +”,而GTK 2.0的程序包名称为“ gtk + -2.0”)。

环境变量
PKG_CONFIG_PATH

用冒号分隔(在Windows中,用分号分隔)的目录列表,以搜索.pc文件。搜索路径后,将始终搜索默认目录。默认值为libdir / pkgconfig:datadir / pkgconfig其中libdir是libdir,其中pkg - config和 datadir是安装pkg - config的datadir 。
PKG_CONFIG_DEBUG_SPEW
如果设置,将导致pkg - config打印各种调试信息并报告所有错误。
PKG_CONFIG_TOP_BUILD_DIR
为魔术变量pc_top_builddir设置的值,该值可能出现在.pc文件中。如果未设置环境变量,则将使用默认值’$(top_builddir)’。此变量应引用Makefile的最高builddir,将在其中使用pkg - config报告的编译/链接标志。这仅在针对尚未安装的软件包进行编译/链接时才重要。

pkg-config 的作用讲解推荐看这个博客pkg-config
比较重要的部分内容是

pkg-config给出了opencv的头文件和库的所有信息!
这有什么好处?
所有用opencv的其他程序,在编译时,只需要写“”,而不需要自己去找opencv的头文件在哪里,要链接的库在哪里!省时省力!
如果你写了一个库,不管是静态的还是动态的,要提供给第三方使用,那除了给人家库/头文件,最好也写一个pc文件,这样别人使用就方便很多,不用自己再手动写依赖了你哪些库,只需要敲一个”pkg-config [YOUR_LIB] –libs –cflags”。

pkg-config的信息从哪里来?
很简单,有2种路径:
第一种:取系统的/usr/lib下的所有*.pc文件。
第二种:PKG_CONFIG_PATH环境变量所指向的路径下的所有*.pc文件。
这些pc文件什么时候有的?都是在你安装某个库/模块的时候,添加的。比如你往系统安装opencv时,就会在/usr/lib/目录下,放一个opencv.pc。

如何添加自己的pc文件
如上文所说,有2种方式.:
第一种:把你的pc文件,直接放到/usr/lib/…默认路径下。
第二种: 把你的pc文件的路径写到PKG_CONFIG_PATH环境变量里。

如何将pc文件的路径添加到PKG_CONFIG_PATH环境变量里呢。

linux下 环境变量

linux下 环境变量讲解推荐看博客:环境变量的区别

主要内容是:

登入系统时读入一些环境变量的配置方案,读取步骤:
当登入系统时候获得一个shell进程时,其读取环境设定档有三步 :
1.首先读入的是全局环境变量设定档/etc/profile,然后根据其内容读取额外的设定的文档,如 /etc/profile.d和/etc/inputrc
2.然后根据不同使用者帐号,去其家目录读取~/.bash_profile,
如果这读取不了就读取~/.bash_login,
这个也读取不了才会读取~/.profile(可以设定本用户专有的路径,环境变量等,它只在登入的时候执行一次),这三个文档设定基本上是一样的,读取有优先关系
3.然后在根据用户帐号读取~/.bashrc (也是某用户专有设定文档,可以设定路径,命令别名,每次shell script的执行都会使用它一次)

若该变量为扩增变量内容时,则可用 “$变量名称”+ 变 量 累 加 内 容 , 如 下 所 示 : 『 P A T H = " {变量} 累加内容,如下所示: 『PATH=" PATH="PATH":/home/bin』
若该变量需要在其他子程序执行,则需要以 export 命令使变量发成环境变量: 『export PATH』
利用 source 或小数点 (.) 都可以将配置文件癿内容读取到目前的 shell 环境中!

配置pkg-config

根据上面的信息
修改bash.bashrc文件

sudo vim ~/.bashrc
//(或者修改其他几个环境配置文件)
//在最后加入:
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/OPENCV_DIR_PATH/lib/pkgconfig
export PKG_CONFIG_PATH
//保存后使用source命令
source /etc/bash.bashrc
//查看变量是否生效
echo $PKG_CONFIG_PATH //可以看见添加成功
pkg-config opencv --libs --cflags //可以看见正确查找opencv

好了,经过上述设置后,就可以使用pkg-config顺利链接opencv了。

//pkg-config 编译链接opencv
g++ test.cpp -o opencvtest1 `pkg-config opencv --cflags --libs`

Linux 下工具 cmake 链接第三方库

findpackage搜索路径

这个问题在CMake官方文档中有非常详细的解答。详细可以查看官方文档。

首先是查找路径的根目录。把几个重要的默认查找目录总结如下:

<package>_DIR
CMAKE_PREFIX_PATH
CMAKE_FRAMEWORK_PATH
CMAKE_APPBUNDLE_PATH
PATH

其中,PATH中的路径如果以binsbin结尾,则自动回退到上一级目录。
找到根目录后,cmake会检查这些目录下的

<prefix>/(lib/<arch>|lib|share)/cmake/<name>*/          (U)
<prefix>/(lib/<arch>|lib|share)/<name>*/                (U)
<prefix>/(lib/<arch>|lib|share)/<name>*/(cmake|CMake)/  (U)

cmake找到这些目录后,会开始依次找<package>Config.cmakeFind<package>.cmake文件。找到后即可执行该文件并生成相关链接信息。

查找路径的根目录中比较重要的一个是PATH。由于/usr/bin/PATH中,cmake会自动去/usr/(lib/<arch>|lib|share)/cmake/<name>*/寻找模块,这使得绝大部分我们直接通过apt-get安装的库可以被找到。

另外一个比较重要的是<package>_DIR。我们可以在调用cmake时将这个目录传给cmake。由于其优先级最高,因此cmake会优先从该目录中寻找,这样我们就可以随心所欲的配置cmake使其找到我们希望它要找到的包。而且除上述指定路径外,cmake还会直接进入<package>_DIR下寻找。
这样做以后,cmake会优先从该目录寻找OpenCV

模块模式中

findpackage指令默认使用模块模式
第一种方式 拷贝或编写find*.cmake文件到搜索路径中
模块模式的搜索路径是什么呢? 我并没有找到文档说明,猜测应该是某个环境变量。应该包括 /usr/share/cmake/Modules,这其中还有很多cmake自带的模块文件
第二种方式 把*.cmake文件所在的路径添加到CMAKE_MODULE_PATH 变量中

CMake searches for a file called Find.cmake in the CMAKE_MODULE_PATH followed by the CMake installation.

CMAKE_MODULE_PATH变量默认为空
用户可以使用set指令指定
常用方式为

//set指令设置CMAKE_MODULE_PATH
set()

如果模块模式没有找到 会使用配置模式继续查找

If no module is found and the MODULE option is not given the command proceeds to Config mode.

这里不做出模块模式的示例了。

配置模式

Config mode attempts to locate a configuration file provided by the package to be found. A cache entry called <package>_DIR is created to hold the directory containing the file

如果模块模式没有找到 那么就在搜索路径中查找
*config.cmake 文件
找到后即可执行该文件并生成相关链接信息。

也可以直接设定_DIR 来指定文件目录

opencv示例-

//CMakeLists.txtt
cmake_minimum_required(VERSION 2.8)
project( testopencv )
//设置搜索路径的CMAKE_PREFIX_PATH变量
set(CMAKE_PREFIX_PATH /home/ywz/WorkSpace/install/share/OpenCV)
//或者直接设定<package>_DIR ,二者选一
set(OpenCV_DIR /home/ywz/WorkSpace/install/share/OpenCV)
find_package( OpenCV REQUIRED )
add_executable( testopencv test.cpp )
target_link_libraries( testopencv ${OpenCV_LIBS} )

但是上面这两种设置方法需要每一个项目都设定,如果是从别的地方下载的工程直接编译是找不到opencv的,每个工程都需要修改cmakelists.txt才能编译成功,不是很方便。还有另一个方法即在~/.bashr 中设置环境变量,这样每个工程都可以找到opencv’库。

sudo gedit ~/.bashrc

添加

CMAKE_PREFIX_PATH=$CMAKE_PREFIX_PATH:/home/ywz/WorkSpace/install/share/OpenCV
export CMAKE_PREFIX_PATH

使其生效

source ~/.bashrc
//这时使用env 查看环境变量
CMAKE_PREFIX_PATH=:/home/ywz/WorkSpace/install/share/OpenCV

这样每个工程都可以使用opencv库而不用显试修改。

Linux 下可执行文件运行时加载第三方库

我们仅仅完成了程序的编译和链接,还有最后一步,程序运行;程序运行需要加载动态链接库并运行,也需要找寻动态链接库的路径,pkg-config仅负责编译链接时头文件和动态链接库的查找。对于程序运行时加载动态链接库,pkg-config就无能为力了,此时需要用到ldconfig命令,该命令为程序运行时提供动态链接库的运行时绑定,通过加载/etc/ld.so.conf下的路径信息,生成动态库的缓存/etc/ld.so.cache,为程序运行时提供动态库的链接;通过ldconfig -p查看动态链接库缓存信息。因此需要将我们的动态链接库路径添加到/etc/ld.so.conf中,运行ldconfig更新cache,就大功告成了。

ldconfig是一个动态链接库管理命令,其目的为了让动态链接库为系统所共享。
man pkg-config
ldconfig的主要用途:
默认搜寻/lilb和/usr/lib,以及配置文件/etc/ld.so.conf内所列的目录下的库文件。
搜索出可共享的动态链接库,库文件的格式为:lib***.so.**,进而创建出动态装入程序(ld.so)所需的连接和缓存文件。
缓存文件默认为/etc/ld.so.cache,该文件保存已排好序的动态链接库名字列表。
ldconfig通常在系统启动时运行,而当用户安装了一个新的动态链接库时,就需要手工运行这个命令。

ldconfig需要注意的地方:
1、往/lib和/usr/lib里面加东西,是不用修改/etc/ld.so.conf文件的,但是添加完后需要调用下ldconfig,不然添加的library会找不到。
2、如果添加的library不在/lib和/usr/lib里面的话,就一定要修改/etc/ld.so.conf文件,往该文件追加library所在的路径,然后也需要重新调用下ldconfig命令。比如在安装MySQL的时候,其库文件/usr/local/mysql/lib,就需要追加到/etc/ld.so.conf文件中。命令如下:
echo “/usr/local/mysql/lib” >> /etc/ld.so.conf
#ldconfig -v | grep mysql
3、如果添加的library不在/lib或/usr/lib下,但是却没有权限操作写/etc/ld.so.conf文件的话,这时就需要往export里写一个全局变量LD_LIBRARY_PATH,就可以了。一般来讲这只是一种临时的解决方案,在没有权限或临时需要的时候使用。

可执行文件如何寻找动态库

在ld的官方文档中,对这个问题有详尽的描述。

The linker uses the following search paths to locate required
shared libraries:
1. Any directories specified by -rpath-link options.

2. Any directories specified by -rpath options. The difference
between -rpath and -rpath-link is that directories specified by
-rpath options are included in the executable and used at
runtime, whereas the -rpath-link option is only effective at
link time. Searching -rpath in this way is only supported by
native linkers and cross linkers which have been configured
with the --with-sysroot option.

3. On an ELF system, for native linkers, if the -rpath and
-rpath-link options were not used, search the contents of the
environment variable “LD_RUN_PATH”.

4. On SunOS, if the -rpath option was not used, search any
directories specified using -L options.

5. For a native linker, the search the contents of the environment
variable “LD_LIBRARY_PATH”.

6. For a native ELF linker, the directories in “DT_RUNPATH” or
“DT_RPATH” of a shared library are searched for shared
libraries needed by it. The “DT_RPATH” entries are ignored if
“DT_RUNPATH” entries exist.

7. The default directories, normally /lib and /usr/lib.

8. For a native linker on an ELF system, if the file
/etc/ld.so.conf exists, the list of directories found in that
file.

If the required shared library is not found, the linker will issue
a warning and continue with the link.

最重要的是第一条,即rpath。这个rpath会在编译时将动态库绝对路径或者相对路径(取决于该动态库的cmake)写到可执行文件中。chrpath工具可以查看这些路径。

>>> chrpath extract_gpu
extract_gpu: RPATH=/usr/local/cuda/lib64:/home/dechao_meng/data/github/temporal-segment-networks/3rd-party/opencv-3.4.4/build/lib

可以看到,OpenCV的动态库的绝对路径被写到了可执行文件中。因此即使可执行文件的位置发生移动,依然可以准确找到编译时的rpath

接下来的问题:如果我把可执行文件复制到了别人的电脑上,或者我的动态库文件的目录发生了改变,怎样让可执行文件继续找到这个动态库呢?其实是在第五条:LD_LIBRARY_PATH。只要将存储动态库的目录加入到LD_LIBRARY_PATH中,可执行文件就能正确找到该目录。

相信经过上述的讲解,不管是多版本的opencv库,还是ROS中的opencv库 ,在应用中都可以熟练解决。
本文的涉及到到的文件完整路径为

.
├── build
│   ├── CMakeCache.txt
│   ├── CMakeFiles
│   ├── cmake_install.cmake
│   ├── Makefile
│   └── testopencv
├── cat.jpeg
├── CMakeLists.txt
├── gccbuild.sh
├── opencvtest
├── opencvtest1
├── pkgbuild.sh
└── test.cpp

2 directories, 12 files

相关文件后续可以在我的github获得。

参考:
Linux man page 手册
Linux 下C++文件 编译 静态/动态 链接库
CMake packages 手册
cmake findpackage 手册
CMake findapackage 博客
opencv环境配置

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

Linux编程的第三方库引用------gcc、pkg-config与CMake一文讲解 的相关文章

  • STM32F4 使用结构体配置功能

    1 IIC配置 void IIC Mode Config void I2C InitTypeDef I2C InitStructure I2C InitStructure I2C Mode 61 I2C Mode I2C IIC模式 I2C
  • 执行 sudo apt-get update 报错:仓库 xxx 没有release文件 / 不再含有release文件

    输入命令 sudo apt get update 报错 这里可以看到有两个问题 xff0c 一个是 ubuntu自己的源连不上了 第二三个红框框 xff0c 一个是 vmware 这个软件 第一个红框框 首先解决第一个问题 archive
  • C++ 发送HTTP请求

    HTTPRequest HTTPRequest是一个用于发出HTTP请求的单头C 43 43 库 您可以将它包含在项目中并使用它 HTTPRequest在macOS Windows Haiku BSD和GNU Linux上进行了测试 xff
  • 小程序、公众号开发报code been used(40163)或invalid code(40029)错误,解决方案--之--搞清楚微信的登录机制,保存登录状态!!!

    x1f4d6 前言 做微信小程序或公众号开发 xff0c 有时我们为了管理用户 xff0c 需要获取用户的openid xff0c unionId等信息 这时会用到微信提供的接口 xff1a code2Session code2Sessio
  • 使用git在vscode中进行版本控制

    版本控制是一件非常cool的事 xff0c 可以将我们的代码按照版本存储 1 首先我们选择一个版本控制工具 xff0c 这里我们选择git xff0c 点击下载安装 xff0c 安装时选择vscode编辑器 2 安装好了之后打开vscode
  • 2.3.1 参数服务器理论模型

    ROS入门 2 3 1 参数服务器理论模型 ROS入门 理论与实践 视频教程镇楼 参数服务器实现是最为简单的 xff0c 该模型如下图所示 该模型中涉及到三个角色 ROS Master 管理者 Talker 参数设置者 Listener 参
  • 4.6.3 编码设置参数

    ROS入门 4 6 3 编码设置参数 ROS入门 理论与实践 视频教程镇楼 编码的方式可以更方便的设置 全局 相对与私有参数 1 C 43 43 实现 在 C 43 43 中 xff0c 可以使用 ros param 或者 ros Node
  • 5.1 TF坐标变换

    ROS入门 5 1 TF坐标变换 ROS入门 理论与实践 视频教程镇楼 机器人系统上 xff0c 有多个传感器 xff0c 如激光雷达 摄像头等 xff0c 有的传感器是可以感知机器人周边的物体方位 或者称之为 坐标 xff0c 横向 纵向
  • 10.1.3 action通信自定义action文件调用(Python)

    ROS入门 10 1 3 action通信自定义action文件调用 Python ROS入门 理论与实践 视频教程镇楼 需求 创建两个ROS 节点 xff0c 服务器和客户端 xff0c 客户端可以向服务器发送目标数据N 一个整型数据 服
  • rosdep

    rosdep 初始化时异常解决方案 rosdep 初始化时异常解决 视频教程 安装构建依赖 在 noetic 最初发布时 xff0c 和其他历史版本稍有差异的是 没有安装构建依赖这一步骤 随着 noetic 不断完善 xff0c 官方补齐了
  • springboot应用集成prometheus监控

    环境参数 xff1a 运行命令 xff1a 1 uname xff0d a xff08 Linux查看版本当前操作系统内核信息 xff09 2 cat proc version xff08 Linux查看当前操作系统版本信息 xff09 3
  • [NVIDIA Jetson Xavier Nx]从刷机烧录到环境配置 记录

    目录 前言一 开机烧录二 环境配置Cuda环境变量配置更新源python环境配置安装Jtop 内存 CPU GPU等等资源监视工具 前言 对进行NVIDIA Jetson Xavier Nx环境配置进行记录 一 开机烧录 参考下面的博客 x
  • 最近处理的报错 -DCMAKE_BUILD_TYPE=Debug

    1 error 39 nullptr 39 was not declared in this scope 解决方法 使用的是QTcreator的pro文件 然后缺少相应关于c 43 43 11的设置 点pro文件中加载的东西如下 QMAKE
  • Halcon 单相机标定

    原文链接 xff1a https blog csdn net weixin 43197380 article details 90438976 comments 13104885 一 理论 为什么要进行单相机标定 xff1f 广义 xff1
  • 将图片嵌入Markdown文档

    将图片嵌入Markdown文档中是一个比较难受的事情 一般大家都会将图片存入本地某个路径或者网络存储空间 xff0c 使用URL链接的形式插入图片 image url to image 将图片放到本地的时候如果想将文档分享给朋友或者换台电脑
  • 自定义的串口通信协议

    自定义的通信协议 自定义一主多从串口通讯 1硬件基础两个从机的 Tx 是相互连接的 xff0c 导致一个从机在需要发送数据时发不出去了 协议思路数据包封装和解封装 树莓派python串口的使用注意更改树莓派串口设备驱动关闭控制台功能pyth
  • Linux串口驱动程序(4)-数据发送

    1 tty数据发送调用关系 怎么样才能找到发送数据所使用的函数呢 xff1f 打开uart register driver函数 xff0c 找到里面的tty register driver xff0c 转到定义 xff0c 这里调用了tty
  • TF 错误:InvalidArgumentError (see above for traceback): Reduction axis 0 is empty in shape [ ]

    Tensorflow python framework errors impl InvalidArgumentError Reduction axis 0 is empty in shape 0 100 Node ArgMax 61 Arg
  • Raspbian安装ROS系统Kinectic|树莓派4B安装ros使用OpenCV(全流程)

    前言 树莓派4B最高拥有4Gb的RAM xff0c 对于承担图像处理任务的嵌入式设计是个性价比很高的选择 众所周知 xff0c ROS系统对Ubuntu系统最友好 xff0c 但是由于树莓派4暂时还无法使用Ubuntu MATE xff0c
  • Ubuntu设置屏幕分辨率及屏幕翻转

    首发于 xff1a yuany3721的WordPress Version Ubuntu 18 04 6 LTS 使用xrandr查看屏幕信息 xrandr Screen 0 minimum 320 x 200 current 1920 x

随机推荐

  • 用美图秀秀换证件照背景颜色

    xff08 JDD KK 原创 xff09 问题描述 xff1a 不会PS xff0c 也没有各种会员 xff0c 怎么为了应急去换证件照背景 xff1f xff08 此方法有局限 xff0c 且质量一般 xff0c 只为应急 xff09
  • 让自己写的程序也有api

    当我们在学习的时候 xff0c 有时候看到别人的api会感觉到蛮高大上的 其实他们的api并不是他们在写完程序之后 xff0c 通过键盘录入的 xff0c 而是通过工具来生生成的 因此我们完全有机会打造属于自己的api api的作用 1 便
  • 记录使用gitlab实现Docker自动化部署

    目录 前言 一 gitlab runner docker安装 二 gitlab runner的注册与使用 1 注册 2 gitlab ci yml 脚本编写 总结 前言 前面搭建了gitlab与harbor xff0c 现在就使用它们来实现
  • ros::ok()

    ros ok 在以下几种情况下会返回false xff1a 按下Ctrl C时 我们被一个同名同姓的节点从网络中踢出 ros shutdown 被应用程序的另一部分调用 所有的ros NodeHandles都被销毁了 一旦ros ok 返回
  • 小觅深度相机标准版 ROS使用

    只写运行起来 xff0c 具体实例运行方法在对应的实例中 系统 xff1a ubuntu16 04 1 安装SDK 下载SDK驱动并解压 xff1a https github com slightech MYNT EYE S SDK 看RE
  • 移动机器人(四)四轴飞行器

    四轴飞行控制原理 四轴飞行器在空间上有6个自由度 xff0c 分别是沿3个坐标轴进行平动和转动 xff0c 通过对四个旋翼的转速控制来实现 xff0c 6个自由度方向的运动姿态分别为 xff1a 垂直升降 俯仰角度 前后飞行 横滚角度 左右
  • (二) 使用vscode

    1 在拉代码过程中 xff0c 使用代码对比工具 左侧有个分支工具 xff0c 点击左侧栏中某个文件 xff0c 右侧出现两栏 以102行为例 xff0c 红色部分为代码改动之前显示 xff0c 右侧绿色部分为代码改动之后显示 2 文件工具
  • 30个实用VSCode 插件,让你的开发效率倍增!

    1 Image preview 通过此插件 xff0c 当鼠标悬浮在图片的链接上时 xff0c 可以实时预览该图片 xff0c 除此之外 xff0c 还可以看到图片的大小和分辨率 2 Auto Rename Tag 使用该插件 xff0c
  • OpenCV 4.5.0+conrtrib 已编译完成(附下载链接)

    OpenCV 4 5 0 43 conrtrib 已编译完成 xff0c 包含编译源码 平台 Windows 43 VS2015 百度网盘链接 提取密码 xff1a rdgh 源码下载 OpenCV源码下载链接推荐 xff08 包含匹配的c
  • 第一篇综述-无人车简介

    综述 无人车简介 xff08 1 xff09 1 1无人车的定义以及分级 1 2无人车的发展历程 参考链接 原文链接 xff1a https blog csdn net thomashtq article details 81161018
  • 在C#中使用Intptr究竟需不需要释放?

    只有是用Marshal 申请的 xff08 AllocHGlobal xff09 这种需要释放 xff1b 对于使用PInvoke 返回的IntPtr不用释放 xff1b 简单来说 xff0c 这个东西是你创建出来的你就得负责回收 xff0
  • .NET中Invoke和BeginInvoke

    在 NET中 xff0c 固定必须主线程才能操作UI界面 xff0c 如果在非主线程中强行对UI界面赋值 xff0c 则会报错 xff0c 跨线程操作UI 是不允许的 xff0c 需要使用Invoke或BeginInvoke xff0c 关
  • php 跨域解决方案

    设置允许访问的域名 xff1a 1 允许全部的域名访问 span class token function header span span class token punctuation span span class token str
  • WPF之转换器

    WPF是一个数据驱动模式 xff0c 开发中都是以数据为中心 xff0c WPF具有数据绑定机制 xff0c 数据有变化时 xff0c 会通知UI进行更新 WPF用的是MVVM模式 MVVM是Model View ViewModel xff
  • CS程序自动更新和手动更新的技术实现

    1 程序启动时检查更新 xff0c 如果可以更新 xff0c 则判断是否为强制性更新 xff0c 如果是则直接强制更新 xff0c 不是则不处理 xff0c 转为到程序更新模块中手动处理 xff0c 这是更新最基本的原理 检查更新 priv
  • 用MATLAB将矩阵数据写入txt文件中,打开乱码原因

    MATLAB将数据写入txt文件中乱码的原因 xff0c 是将数据按照二进制文件写入txt文件 xff0c 所以打开会出现乱码的情况 xff0c 只需要把 fid1 61 fopen 39 piture txt 39 39 w 39 换成
  • boost C++知识点(一)

    1 boost总览 xff1a Boost Any Boost Any 提供了一个名为 boost any 的数据类型 xff0c 可以存放任意的类型 例如 xff0c 一个类型为 boost any 的变量可以先存放一个 int 类型的值
  • python 函数里面直接修改函数外部的全局变量

    python函数内部对全局变量进行修改 全局变量为immutable 不可变的 全局变量为mutable 可变的 全局变量为immutable 不可变的 a span class token operator 61 span span cl
  • ubuntu20.04中安装ROS系统

    自从在自己的电脑上安装了ubuntu20 04 43 window10双系统之后 xff0c 为了下一步开展研究 xff0c 所以安装ROS系统 把安装过程记录下来 xff0c 方便以后学习 亲测有效 xff01 xff01 xff01 x
  • Linux编程的第三方库引用------gcc、pkg-config与CMake一文讲解

    众所周知 linux 下库文件编译三部曲 config make makeinstall configure过程中可能会遇到无法找到某些头文件和动态库 xff1b 原因有两个 xff1a xff08 1 xff09 系统没有这些头文件和动态