您好,登錄后才能下訂單哦!
本篇內容介紹了“Qt加載libjpeg庫出現“長跳轉已經運行”錯誤問題如何解決”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
在我以為升級到 Qt5.15.9 后,運行沒有什么問題時,問題就來了
在加載 jpeg 格式的圖片時,出現了“長跳轉已經運行”的錯誤
這個錯誤一般是由 setjmp/longjmp 函數觸發的,出現的可能的原因有以下幾種(聽聽 chatgpt 的回答)
longjmp 是 C 標準庫中的一個函數,用于跳轉到之前通過 setjmp 函數設置的跳轉點,并在跳轉時返回指定的錯誤碼。如果在調用 longjmp 函數時出現錯誤,通常會表現為程序異常終止、崩潰或死鎖等問題。
longjmp 函數可能出現錯誤的原因和解決方法如下:
1.調用 setjmp 的函數已經返回
使用 longjmp 函數必須要在之前調用過 setjmp 函數并且還沒有從 setjmp 函數返回時才能使用。如果在 setjmp 函數返回后再調用 longjmp 函數,就會導致未定義行為,可能會導致程序崩潰或死鎖。解決方法是檢查 longjmp 函數的調用時機,并確保它是在 setjmp 函數之后而且還沒有從 setjmp 函數返回時調用的。
2.跳轉目標不存在
當 longjmp 函數嘗試跳轉到之前設置的跳轉點時,如果該跳轉點已經不存在,就會導致錯誤。這種情況通常發生在跳轉點所在的函數已經返回或者被釋放時。解決方法是檢查跳轉點是否存在,并確保跳轉點所在的函數仍然有效。
3.跨線程調用
longjmp 函數通常不適用于多線程程序。如果在一個線程中設置了跳轉點,然后在另一個線程中調用 longjmp 函數來跳轉到該點,就會導致未定義行為。解決方法是使用線程安全的異常處理機制來代替 longjmp 和 setjmp 函數。
4.其他原因
除了上述幾種情況外,還有可能是其他一些原因導致 longjmp 錯誤。例如,內存泄漏、非法指針訪問、堆棧溢出等問題都可能導致 longjmp 函數失敗。解決方法是根據具體錯誤信息進行排查和修復。
我這邊是觸發 ERREXIT2 后而跳出的錯誤
ERREXIT2 的原型如下
觸發 ERREXIT2,進入 my_error_exit 函數,然后調用 longjmp,最后程序異常崩潰
為何有這種丑陋的報錯呢?官方應該可以把這種報錯 catch 下來,而不是讓程序閃退,看看 llbjpeg-turbo 作者給出的解釋
簡單說來,ERREXIT 是官方的 libjpeg 遺留下來的,代碼很古老,至今沒人修,而 libjpeg-turbo 只是包裝了 libjpeg 庫,這樣加載更快,對 libjpeg 中的 api 沒有任何改變,他也可以幫忙包裝下這個報錯,只是要加錢
話說回來,我為何會遇到 ERREXIT 呢?
那就不得不說 Qt 對 5.15 后續版本做出的一些改動了
就是說 libjpeg 要你自己去鏈接,我們不再幫你集成到 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 的錯誤,但是使用 loadFromData 加載 jpeg 圖片數據還是會報錯
QImage photo;
photo.loadFromData(buffer.GetBuffer(), buffer.GetBufferLen()); // buffer 里放置 jpeg 圖片數據
我第一反應是 libjpeg-turbo 的庫版本太高了,就查閱低版本的庫,想通過 vcpkg 新出的版本控制來實現的,奈何水平有限,沒弄出來,就去官網下載 2.1.3 的壓縮包自己編譯
之所以編譯 2.1.3 的包,是因為 Qt5.15.9 版本將 libjpeg-turbo 更新至 2.1.3
編譯出一個 lib 庫后,鏈接到程序中,還是會報錯,嗯,那先排除 libjpeg 版本問題
從堆棧下手吧,一層一層的剝開問題表皮,看本質
報錯是停在紅框中的 ERREXIT2 中,單步調試后發現,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
是我大意了,附上編譯命令,
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加載libjpeg庫出現“長跳轉已經運行”錯誤問題如何解決”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。