首页 > 其他分享 >Qt 加载 libjpeg 库出现“长跳转已经运行”错误

Qt 加载 libjpeg 库出现“长跳转已经运行”错误

时间:2023-04-21 18:00:43浏览次数:47  
标签:longjmp 函数 libjpeg 编译 跳转 Qt qt

继上篇 Qt5.15.0 升级至 Qt5.15.9 遇到的一些错误

篇幅有点长,先说解决方法,在编译静态库时加上 -qt-libjpeg,编译出 libjpeg 库后,在项目中使用 #pragma comment 链接即可


 

在我以为升级到 Qt5.15.9 后,运行没有什么问题时,问题就来了

在加载 jpeg 格式的图片时,出现了“长跳转已经运行”的错误

这个错误一般是由 setjmp 函数触发的,出现的可能的原因有以下几种(听听 chatgpt 的回答)


 

longjmp 是 C 标准库中的一个函数,用于跳转到之前通过 setjmp 函数设置的跳转点,并在跳转时返回指定的错误码。如果在调用 longjmp 函数时出现错误,通常会表现为程序异常终止、崩溃或死锁等问题。

longjmp 函数可能出现错误的原因和解决方法如下:

  1. 调用 setjmp 的函数已经返回

使用 longjmp 函数必须要在之前调用过 setjmp 函数并且还没有从 setjmp 函数返回时才能使用。如果在 setjmp 函数返回后再调用 longjmp 函数,就会导致未定义行为,可能会导致程序崩溃或死锁。解决方法是检查 longjmp 函数的调用时机,并确保它是在 setjmp 函数之后而且还没有从 setjmp 函数返回时调用的。

  1. 跳转目标不存在

当 longjmp 函数尝试跳转到之前设置的跳转点时,如果该跳转点已经不存在,就会导致错误。这种情况通常发生在跳转点所在的函数已经返回或者被释放时。解决方法是检查跳转点是否存在,并确保跳转点所在的函数仍然有效。

  1. 跨线程调用

longjmp 函数通常不适用于多线程程序。如果在一个线程中设置了跳转点,然后在另一个线程中调用 longjmp 函数来跳转到该点,就会导致未定义行为。解决方法是使用线程安全的异常处理机制来代替 longjmp 和 setjmp 函数。

  1. 其他原因

除了上述几种情况外,还有可能是其他一些原因导致 longjmp 错误。例如,内存泄漏、非法指针访问、堆栈溢出等问题都可能导致 longjmp 函数失败。解决方法是根据具体错误信息进行排查和修复。


 

我这边是触发 ERREXIT2 后而跳出的错误

为何有这种丑陋的报错呢?官方应该可以把这种报错 catch 下来,而不是让程序闪退,看看 llbjpeg-turbo 作者给出的解释

原始链接:Possibility of non-unwinding error handling

简单说来,ERREXIT 是官方的 libjpeg 遗留下来的,代码很古老,至今没人修,而 libjpeg-turbo 只是包装了 libjpeg 库,这样加载更快,对 libjpeg 中

的 api 没有任何改变,他也可以帮忙包装下这个报错,只是要加钱

话说回来,我为何遇到 ERREXIT 呢?

那就不得不说 Qt 对 5.15 后续版本做出的一些改动了

 见:https://doc.qt.io/qt-5/qtgui-attribution-libjpeg.html

就是说 jpeg 要你自己去链接,我们不再帮你集成到 qjpeg.lib 中了,应该是因为协议问题

Independent JPEG Group License and BSD 3-Clause "New" or "Revised" License and zlib License.

 

既然问题找到了,那解决方法“应该”也能浮出水面了,对,打上双引号的应该

是我低估了这个问题,在我以为自己加个 libjpeg-turbo 的库之后就能万事大吉时,结果往往给你一个大嘴巴子

我用 vcpkg 包管理器添加了 libjpeg-turbo:x86-windows-static,程序编译通过,再没有出现 ERROR2019 的错误,但是加载 jpeg 图片还是会报错

我以为是 libjpeg-turbo 的库版本太高了,就查阅低版本的库,想通过 vcpkg 新出的版本控制来实现的,奈何水平有限,没弄出来,就去官网下载 2.1.3 的压缩包自己编译

QT5.15.9 版本更新中包括将 libjpeg-turbo 更新至 2.1.3

见:https://code.qt.io/cgit/qt/qtreleasenotes.git/about/qt/5.15.9/release-note.md

编译出一个 lib 库后,再链接到程序中,还是会报错,嗯,先排除 libjpeg 版本问题

那就从堆栈下手吧,一层一层的剥开问题,看本质

 qt 里要求 libjpeg-turbo 的 version 为 80,而 vcpkg 提供的所有 libjpeg-turbo 版本都是 62,在 jconfig.h 中查看 version

 

嗯,80 的为 qt 专属,这就解释了为啥触发了 ERREXIT2 了,顺便说一句,vcpkg 提供的库其实就是官方的库,libjpeg-turbo 不管是 2.1.5 还是 2.1.3,JPEG_LIB_VERSION 都是 62

因此我们只要编译一个 libjpeg 的 qt 三方库就行了

借助这篇教程

使用 Qt Creator(我使用的 Qt Creator 10.0.0) 打开 libjpeg.pro,再在 .pro 文件里改 lib 输出路径就行

 

顺便贴上构建设置

可能需要将 jom.exe 改成 nmake.exe(打开 pro 项目后,在构建和运行中选择)

这些都准备后,点击编译即可,在 lib 文件夹中就可以找到了

把库放到项目文件的库目录下,并静态绑定即可

 


 

是不是很复杂,直到上一步我也是这么以为的,在我全局搜索 qtlibjpeg.lib 时,我发现 qt 下已经给你编译好了

惊不惊喜意不意外(我都要骂娘了)

重新阅读了官方文档,上面说你可以选择在编译静态库时添加一些参数来一起编译你需要的三方库,比如 libjpeg

见:https://doc.qt.io/archives/qt-6.0/configure-options.html#third-party-libraries

是我大意了,附上编译命令,

configure -static -static-runtime -debug-and-release -mp -prefix "..\msvc2019_x86_static" -opensource -confirm-license -optimize-size -qt-libjpeg -make libs -nomake examples -nomake tests -skip qtwebengine

编译出的库文件就在 lib 下

 

小结:还是对 Qt 的库配置不熟悉,导致花了大量工夫来解决这种问题;好在有了这次经验后,以后再遇到类似问题,就能手到擒来了

 

标签:longjmp,函数,libjpeg,编译,跳转,Qt,qt
From: https://www.cnblogs.com/strive-sun/p/17341282.html

相关文章

  • Qt之QMake编译转换为CMake编译
    一、前言-QMake和CMake都是用来控制编译过程的构建系统,最终生成可在选择的编译器环境中使用的本机makefile和工作区。简单来说,QMake和CMake就像类似于作曲,makefile类似于乐谱,最终由编译器完成乐章的演奏。那么QMake和CMake有什么区别呢?-对于纯Qt项目,QMake更加好用。QMake与QtCr......
  • Qt5.14+CMake3.22+OpenCV4.5
    原文地址zhuanlan.zhihu.com下载链接首先需要下载对应的软件,下载链接和我选择的版本如下(仅作参考):QtIndexof/archive/qt/5.14/5.14.2,qt-opensource-windows-x86-5.14.2.exeCMakeDownload|CMake,cmake-3.23.0-windows-x86_64.msi注意x86指的是32位系统;x64指的是64位系......
  • MQTT-发布与订阅的报文
    MQTT发布订阅流程在MQTT发布/订阅模式中,一个客户端既可以是发布者,也可以是订阅者,也可以同时具备这两个身份。当客户端发布一条消息时,它会被发送到代理,然后代理将消息路由到该主题的所有订阅者。当客户端订阅一个主题时,它会收到代理转发到该主题的所有消息发布消息报文-Publish......
  • Qt使用Http协议进行通信
    原文地址blog.csdn.net原文链接在使用Qt框架进行应用开发的过程中,很多时候需要进行客户端与服务端的网络通信,这时候就需要Qt的internet模块。而网络通信中最常用的协议就是http协议,Qt对http协议的调用进行了封装,使用非常方便。这里对常用的http请求demo做一下总结,方便大家参......
  • MQTT基础介绍
    MQTT与HTTP的区别HTTP协议是客户端与服务端直连请求与响应MQTT是基于发布订阅模型的轻量级的消息传输协议MQTT能力发布:Publish订阅:Subscribe代理:Broker,管理通信执行模式:客户端发送消息到broker,broker将消息发送给订阅过的客户端MQTT通信模式一对一:点对点通信......
  • ImportError: DLL load failed while importing QtChart: 找不到指定的模块
    这个错误通常是由于您的Python环境缺少QtChart模块或QtChart模块依赖的库文件之一导致的。解决此问题的方法可能因操作系统和Python环境而异,但下面是一些常见的解决方法:检查是否已安装QtChart模块和其依赖项。您可以使用pip命令在终端中安装QtChart模块:Copycodepipinstal......
  • MQTT报文分析
    一、问题引入MQTT属于应用层协议,基于TCP/IP架构实现,那么它的报文是如何定义的呢?或许可以像分析http协议那样,利用抓包工具:wireshark分析报文。二、解决过程......
  • 项目-mqtt阿里云传输图像,AD,10路输入,8路输出
     程序下载1,配置阿里云物联网平台参数 2,下载程序   3,正常运行阿里云物联网平台会显示设备在线  提示:上报开关量等数据设备发布的主题为: /a1ykoHAGGPL/${deviceName}/user/update上报摄像头数据设备发布的主题为:  /a1ykoHAGGPL/${deviceName}/use......
  • Qt编写推流综合应用示例(文件推流/桌面推流/本地摄像头/网络摄像头/转发推流/视频分发)
    一、功能特点1.1文件推流指定网卡和监听端口,接收网络请求推送音视频等各种文件。实时统计显示每个文件对应的访问数量、总访问数量、不同IP地址访问数量。可指定多种模式,0-直接播放、1-下载播放。实时打印显示各种收发请求和应答数据。每个文件对应MD5加密的唯一标识符,用......
  • QT----富文本操作
    1.富文本主要的架构:2.最主要的光标切换函数moveCursor()3.不同行显示不同的背景,相同行显示不同的字体效果如下: 主要代码:QTextBlockFormatdefaultFormat=ui->textBrowser->textCursor().blockFormat();QTextCursorcursorRoot=ui->textBrowser->textCursor();......