Qt?加載?libjpeg?庫出現(xiàn)“長跳轉已經(jīng)運行”錯誤問題解決
參考資料:Qt5.15.0 升級至 Qt5.15.9 遇到的一些錯誤
篇幅有點長,先說解決方法,在編譯靜態(tài)庫時加上 -qt-libjpeg,編譯出 libjpeg 庫后,在項目中使用 #pragma comment 鏈接即可
OK,開始回顧痛苦經(jīng)歷
在我以為升級到 Qt5.15.9 后,運行沒有什么問題時,問題就來了
在加載 jpeg 格式的圖片時,出現(xiàn)了“長跳轉已經(jīng)運行”的錯誤
這個錯誤一般是由 setjmp/longjmp 函數(shù)觸發(fā)的,出現(xiàn)的可能的原因有以下幾種(聽聽 chatgpt 的回答)
longjmp 是 C 標準庫中的一個函數(shù),用于跳轉到之前通過 setjmp 函數(shù)設置的跳轉點,并在跳轉時返回指定的錯誤碼。如果在調(diào)用 longjmp 函數(shù)時出現(xiàn)錯誤,通常會表現(xiàn)為程序異常終止、崩潰或死鎖等問題。
longjmp 函數(shù)可能出現(xiàn)錯誤的原因和解決方法如下:
1.調(diào)用 setjmp 的函數(shù)已經(jīng)返回
使用 longjmp 函數(shù)必須要在之前調(diào)用過 setjmp 函數(shù)并且還沒有從 setjmp 函數(shù)返回時才能使用。如果在 setjmp 函數(shù)返回后再調(diào)用 longjmp 函數(shù),就會導致未定義行為,可能會導致程序崩潰或死鎖。解決方法是檢查 longjmp 函數(shù)的調(diào)用時機,并確保它是在 setjmp 函數(shù)之后而且還沒有從 setjmp 函數(shù)返回時調(diào)用的。
2.跳轉目標不存在
當 longjmp 函數(shù)嘗試跳轉到之前設置的跳轉點時,如果該跳轉點已經(jīng)不存在,就會導致錯誤。這種情況通常發(fā)生在跳轉點所在的函數(shù)已經(jīng)返回或者被釋放時。解決方法是檢查跳轉點是否存在,并確保跳轉點所在的函數(shù)仍然有效。
3.跨線程調(diào)用
longjmp 函數(shù)通常不適用于多線程程序。如果在一個線程中設置了跳轉點,然后在另一個線程中調(diào)用 longjmp 函數(shù)來跳轉到該點,就會導致未定義行為。解決方法是使用線程安全的異常處理機制來代替 longjmp 和 setjmp 函數(shù)。
4.其他原因
除了上述幾種情況外,還有可能是其他一些原因導致 longjmp 錯誤。例如,內(nèi)存泄漏、非法指針訪問、堆棧溢出等問題都可能導致 longjmp 函數(shù)失敗。解決方法是根據(jù)具體錯誤信息進行排查和修復。
我這邊是觸發(fā) ERREXIT2 后而跳出的錯誤
ERREXIT2 的原型如下
觸發(fā) ERREXIT2,進入 my_error_exit 函數(shù),然后調(diào)用 longjmp,最后程序異常崩潰
為何有這種丑陋的報錯呢?官方應該可以把這種報錯 catch 下來,而不是讓程序閃退,看看 llbjpeg-turbo 作者給出的解釋
原始鏈接:Possibility of non-unwinding error handling
簡單說來,ERREXIT 是官方的 libjpeg 遺留下來的,代碼很古老,至今沒人修,而 libjpeg-turbo 只是包裝了 libjpeg 庫,這樣加載更快,對 libjpeg 中的 api 沒有任何改變,他也可以幫忙包裝下這個報錯,只是要加錢
話說回來,我為何會遇到 ERREXIT 呢?
那就不得不說 Qt 對 5.15 后續(xù)版本做出的一些改動了
見:https://doc.qt.io/qt-5/qtgui-attribution-libjpeg.html
就是說 libjpeg 要你自己去鏈接,我們不再幫你集成到 qjpeg.lib 中了,可能是協(xié)議問題
Independent JPEG Group License and BSD 3-Clause "New" or "Revised" License and zlib License.
既然問題找到了,那解決方法“應該”也能浮出水面了,對,打上雙引號的應該
事實上是我低估了這個問題,原本我以為加個 libjpeg-turbo 的庫之后就能萬事大吉時,結果往往給你一個嘴巴子
我用 vcpkg 包管理器添加了 libjpeg-turbo:x86-windows-static,程序編譯通過,也沒有出現(xiàn) ERROR2019 的錯誤,但是使用 loadFromData 加載 jpeg 圖片數(shù)據(jù)還是會報錯
QImage photo;
photo.loadFromData(buffer.GetBuffer(), buffer.GetBufferLen()); // buffer 里放置 jpeg 圖片數(shù)據(jù)
我第一反應是 libjpeg-turbo 的庫版本太高了,就查閱低版本的庫,想通過 vcpkg 新出的版本控制來實現(xiàn)的,奈何水平有限,沒弄出來,就去官網(wǎng)下載 2.1.3 的壓縮包自己編譯
之所以編譯 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 版本問題
從堆棧下手吧,一層一層的剝開問題表皮,看本質
報錯是停在紅框中的 ERREXIT2 中,單步調(diào)試后發(fā)現(xiàn),qt 里要求 libjpeg-turbo 的 version 為 80,而 vcpkg 提供的所有 libjpeg-turbo 版本都是 62,可以在 jconfig.h 中查看 version
嗯,80 的為 qt 專屬,這就解釋了為啥觸發(fā)了 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 文件夾中就可以找到了
把庫放到項目文件的庫目錄下,并靜態(tài)綁定即可
是不是很復雜,直到上一步我也是這么以為的,在我全局搜索 qtlibjpeg.lib 時,我發(fā)現(xiàn) qt 下已經(jīng)給你編譯好了
驚不驚喜意不意外(我都要罵娘了)
重新閱讀了官方文檔,上面說你可以選擇在編譯靜態(tài)庫時添加一些參數(shù)來一起編譯你需要的三方庫,比如 libjpeg
見:https://doc.qt.io/archives/qt-6.0/configure-options.html
是我大意了,附上編譯命令,
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 的庫配置不熟悉,導致花了大量工夫來解決這種問題;好在有了這次經(jīng)驗后,以后再遇到類似問題,就能手到擒來了
到此這篇關于Qt 加載 libjpeg 庫出現(xiàn)“長跳轉已經(jīng)運行”錯誤的文章就介紹到這了,更多相關Qt 加載 libjpeg 庫內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
到此這篇關于Qt 加載 libjpeg 庫出現(xiàn)“長跳轉已經(jīng)運行”錯誤問題解決的文章就介紹到這了,更多相關Qt 加載 libjpeg 庫內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
C++中為何推薦要把基類析構函數(shù)設置成虛函數(shù)
這篇文章主要介紹了C++中為何推薦要把基類析構函數(shù)設置成虛函數(shù)問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-12-12vs2019永久配置opencv開發(fā)環(huán)境的方法步驟
這篇文章主要介紹了vs2019永久配置opencv開發(fā)環(huán)境的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-03-03C++ push方法與push_back方法的使用與區(qū)別
這篇文章主要介紹了C++ push方法與push_back方法的使用與區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-12-12c++利用stl set_difference對車輛進出區(qū)域進行判定
這篇文章主要介紹了set_difference,用于求兩個集合的差集,結果集合中包含所有屬于第一個集合但不屬于第二個集合的元素,需要的朋友可以參考下2017-03-03