【QT入門到晉級】QT打動態庫包及引入動態庫包

前言

? ? ? ? 本篇為持續更新狀態,內容包含window、Linux下打動態庫包,以及引入動態庫包的方式。

一、window

1、動態庫打包

以百度的OCR接口調用打dll庫為例,以下為qtcreator創建動態庫過程:

1.1Qtcreator創建lib項目

創建成功后,即包含以下5個文件,其中baiduocrlib.h和baiduocrlib.cpp是生成動態庫文件的主要文件,baiduocrlib_global.h是引入baiduocrlib動態庫時,必須包含的文件(在引入動態庫時詳細介紹)。

1.2修改動態庫輸出目錄

動態庫是通過“構建”生成的,不能“運行”生成,在.pro文件中,加入一行

#在baiduocrlib.cpp的同級目錄,創建一個dll目錄,生成的動態庫將存在此目錄下
DESTDIR = ../dll

點擊左下角的“錘子”進行項目構建,即可在dll下看到生成的動態庫文件,如下圖所示

1.3編寫動態庫內容

與常規編寫的類是一樣,即在頭文件中定義,在cpp文件中定義,頭文件baiduocrlib.h內容如下


#ifndef BAIDUOCRLIB_H
#define BAIDUOCRLIB_H#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QEventLoop>
#include <QUrl>
#include <QUrlQuery>
#include <QJsonDocument>
#include <QJsonObject>
#include <QObject>
#include <QDebug>
#include <QFile>
#include <QImage>
#include <QBuffer>
#include <QtCore/qglobal.h>#if defined(BAIDUOCRLIB_LIBRARY)
#  define BAIDUOCRLIB_EXPORT Q_DECL_EXPORT
#else
#  define BAIDUOCRLIB_EXPORT Q_DECL_IMPORT
#endifclass BAIDUOCRLIB_EXPORT Baiduocrlib
{
public:Baiduocrlib();QByteArray  block_post_data(const QNetworkRequest& request,const QUrlQuery& postData);QString get_access_token(const QString& client_id,const QString& client_secret) ;QByteArray get_ocr_data_by_png(const QString& access_token,const QString& img_base64_content);QByteArray get_ocr_data_by_pdf(const QString& access_token,const QString& pdf_base64_content);int get_pdf_urlcontent(const QString& pdfFilePath,QString& urlEncodedString);int  get_img_urlcontent(const QString& imagePath,QString& urlEncodedString);
};#endif // BAIDUOCRLIB_H

cpp文件baiduocrlib.cpp內容如下

#include "baiduocrlib.h"Baiduocrlib::Baiduocrlib()
{
}QString Baiduocrlib::get_access_token(const QString& client_id,const QString& client_secret) {QString access_token;QUrl url("https://aip.baidubce.com/oauth/2.0/token");QNetworkRequest request(url);request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");request.setRawHeader("Accept", "application/json");// 創建 POST 數據QUrlQuery postData;postData.addQueryItem("grant_type", "client_credentials");postData.addQueryItem("client_id", client_id);postData.addQueryItem("client_secret", client_secret);//發送Post包(通過阻塞方式獲取返回結果)QByteArray jsonData=block_post_data(request,postData);// 解析 JSON 數據QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData);if (jsonDoc.isNull()) {qDebug() << "Failed to create JSON doc.";return "";}// 檢查 JSON 文檔類型if (jsonDoc.isObject()) {QJsonObject jsonObj = jsonDoc.object();//qDebug() << "JSON Object:" << jsonObj;// 訪問 JSON 對象中的數據if (jsonObj.contains("access_token")) {access_token = jsonObj["access_token"].toString();qDebug() << "access_token:" << access_token;}} else {qDebug() << "JSON is not an object.";}return access_token;
}QByteArray Baiduocrlib::block_post_data(const QNetworkRequest& request,const QUrlQuery& postData){//QString resstr;QByteArray responseData;// 創建網絡訪問管理器QNetworkAccessManager block_manager;// 發送POST請求QNetworkReply* reply = block_manager.post(request, postData.toString(QUrl::FullyEncoded).toUtf8());// 創建一個事件循環來阻塞當前線程QEventLoop loop;QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);// 阻塞當前線程直到網絡請求完成loop.exec();// 檢查請求結果if (reply->error() == QNetworkReply::NoError) {// 請求成功,處理返回的數據/*QByteArray */responseData = reply->readAll();//resstr = QString::fromUtf8(responseData);//qDebug() << __LINE__ <<"Response:" << resstr;} else {// 請求失敗,處理錯誤qDebug() << "Error:" << reply->errorString();responseData="";}// 清理reply->deleteLater();return responseData;
}QByteArray Baiduocrlib::get_ocr_data_by_png(const QString& access_token,const QString& img_base64_content){//QString urlstr=QString("https://aip.baidubce.com/rest/2.0/ocr/v1/general?access_token=%1").arg(access_token);//標準含位置版本QString urlstr=QString("https://aip.baidubce.com/rest/2.0/ocr/v1/accurate?access_token=%1").arg(access_token);//高精度含位置版本QUrl url(urlstr);QNetworkRequest request(url);request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");request.setRawHeader("Accept", "application/json");// 創建 POST 數據QUrlQuery postData;postData.addQueryItem("image", img_base64_content);postData.addQueryItem("detect_direction", "false");postData.addQueryItem("paragraph", "false");postData.addQueryItem("probability", "false");postData.addQueryItem("multidirectional_recognize", "false");//發送Post包(通過阻塞方式獲取返回結果)QByteArray jsonData=block_post_data(request,postData);//qDebug() << __LINE__ <<"jsonData:" << jsonData;return jsonData;
}QByteArray Baiduocrlib::get_ocr_data_by_pdf(const QString& access_token,const QString& pdf_base64_content){qDebug() << __LINE__ << __FUNCTION__;//QString urlstr=QString("https://aip.baidubce.com/rest/2.0/ocr/v1/general?access_token=%1").arg(access_token);//標準含位置版本QString urlstr=QString("https://aip.baidubce.com/rest/2.0/ocr/v1/accurate?access_token=%1").arg(access_token);//高精度含位置版本QUrl url(urlstr);QNetworkRequest request(url);request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");request.setRawHeader("Accept", "application/json");// 創建 POST 數據QUrlQuery postData;postData.addQueryItem("pdf_file", pdf_base64_content);postData.addQueryItem("detect_direction", "false");postData.addQueryItem("paragraph", "false");postData.addQueryItem("probability", "false");postData.addQueryItem("multidirectional_recognize", "false");//發送Post包(通過阻塞方式獲取返回結果)QByteArray jsonData=block_post_data(request,postData);//qDebug() << __LINE__ <<"jsonData:" << jsonData;return jsonData;
}int Baiduocrlib::get_pdf_urlcontent(const QString& pdfFilePath,QString& urlEncodedString){// 讀取 PDF 文件QFile file(pdfFilePath);if (!file.open(QIODevice::ReadOnly)) {qDebug() << "無法打開文件:" << pdfFilePath;return -1;}QByteArray pdfData = file.readAll();file.close();// Base64 編碼QByteArray base64Encoded = pdfData.toBase64();// URL 編碼urlEncodedString = QUrl::toPercentEncoding(base64Encoded);return 0;
}int Baiduocrlib::get_img_urlcontent(const QString& imagePath,QString& urlEncodedString){// 加載圖片QImage image(imagePath);if (image.isNull()) {qDebug() << "無法加載圖片:" << imagePath;return -1;}// 將圖片保存到QByteArray中QByteArray byteArray;QBuffer buffer(&byteArray);buffer.open(QIODevice::WriteOnly);// 將圖片保存為PNG格式,你也可以選擇其他格式如JPEGif (!image.save(&buffer, "PNG")) {qDebug() << "無法將圖片保存到緩沖區";return -1;}buffer.close();// 將二進制數據轉換為Base64編碼QByteArray base64Data = byteArray.toBase64();// 轉換為QStringQString base64String = QString::fromLatin1(base64Data);// URL編碼urlEncodedString = QUrl::toPercentEncoding(base64String);qDebug() << __LINE__ << urlEncodedString.size();return 0;
}

1.4生成的動態庫

以上內容進行構建之后,在dll目錄下將會看到兩個文件Baiduocrlib.dll和libBaiduocrlib.a

主要是使用xxx.dll文件,引用前最好把頭文件也放在同一個目錄下(別的項目引用此動態庫時,需要引用到這個頭文件)。

2、動態庫引入

上面生成了兩個文件:dll和.a(mingw32編譯器生成的動態庫),其他項目引入時,只需要其中一個動態庫文件

1、在.pro文件中加入以下示例內容

#創建lib目錄,把commdll.dll文件和commdll.h文件放到lib目錄下HEADERS += \lib/commdll.h \            #增加頭文件,通過頭文件來引用mainwindow.h
LIBS +=-L$$PWD/lib -lcommdll   # $$PWD表示當前路徑

然后在mainwindow.h文件中加入#include "lib/commdll.h"即可,調用時,按照常規類的方式來調用,可以理解為dll文件封裝了自定義類。

Linux

1、動態庫打包

linux下Qtcreator生成動態庫的操作方法與window是一樣的,區別是Linux下生成的是so文件

2、動態庫引入

除了window中直接修改.pro文件,也可以在qtcreator中添加庫,如下所示:

2.1右鍵點擊左上角的項目,選中右鍵菜單【添加庫】

2.2 選中【外部庫】,點擊下一步

2.3

2.3 選擇library type類型為【Linux(lib*.so,lib*.a)】,選擇庫文件和路徑,點擊下一步

2.4點擊完成即可

在pro文件中,可看到如下信息,還缺動態庫的頭文件,在HEADERS中加上動態庫的頭文件即可

結尾

? ? ? ? QT打包的動態庫SO包,后臺g++編譯的程序不一定能調用,受g++版本,以及QT的依賴庫等因素的影響。如果一個SO包既要同時支持g++編譯的程序和QT程序調用,可以用傳統C/C++的打包方式【Linux C/C++開發】編譯及引用so動態庫。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/901731.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/901731.shtml
英文地址,請注明出處:http://en.pswp.cn/news/901731.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Uniapp: 大綱

目錄 一、基礎鞏固1.1、Uniapp:下拉選擇框ba-tree-picker1.2、Uniapp&#xff1a;確認框1.3、Uniapp&#xff1a;消息提示框1.4、Uniapp&#xff1a;列表提示框1.5、Uniapp&#xff1a;獲取當前定位坐標 二、項目配置2.1、Uniapp&#xff1a;修改端口號2.2、Uniapp&#xff1a;…

WPF 從Main()方法啟動

1.去掉App.xaml StartupUri“MainWindow.xaml” 只會讓App.g.cs 不生成這行代碼&#xff0c;但是還是會生成的App.g.cs文件中生成Main方法 this.StartupUri new System.Uri("MainWindow.xaml", System.UriKind.Relative);默認的App.xaml的生成操作是 應用程序定義…

ADB的安裝及抓取日志(2)

三、ADB抓取日志 在使用ADB抓取日志前&#xff0c;首先要保證電腦已經安裝并配置ADB&#xff0c;在上一節已經驗證完成。連接設備&#xff1a;可通過USB或者WI-FI&#xff0c;將安卓設備與電腦連接&#xff0c;并啟用USB調試模式&#xff0c;此處我選擇的是通過電腦與安卓設備…

opencv 灰度實驗

opencv 灰度實驗 1. 最大值法2. 平均值法3. 加權均值法4(直接讀取灰度圖)cv2.IMREAD_GRAYSCALE5內置將原圖轉換為灰度圖cv2.cvtColor()6 兩個極端的灰度值 灰度圖與彩色圖最大的不同就是&#xff1a;彩色圖是由R、G、B三個通道組成&#xff0c;而灰度圖只有一個通道&#xff0c…

『Kubernetes(K8S) 入門進階實戰』實戰入門 - Pod 詳解

『Kubernetes(K8S) 入門進階實戰』實戰入門 - Pod 詳解 Pod 結構 每個 Pod 中都可以包含一個或者多個容器&#xff0c;這些容器可以分為兩類 用戶程序所在的容器&#xff0c;數量可多可少Pause 容器&#xff0c;這是每個 Pod 都會有的一個根容器&#xff0c;它的作用有兩個 可…

用 Vue 3 實現一個拖拽排序表格組件(支持列/行重排、列寬調整)

文章目錄 一、項目初始化1.1 技術棧說明1.2 項目結構圖&#xff08;Mermaid&#xff09; 二、構建基礎表格組件2.1 創建基本表格結構 三、實現行拖拽排序3.1 安裝依賴3.2 使用 vuedraggable 實現拖拽 四、實現列寬拖拽調整4.1 基本樣式設置4.2 添加拖拽邏輯 五、實現列拖拽排序…

Python異常處理全面指南

目錄 一、異常處理概述 1.1 什么是異常&#xff1f; 1.2 常見異常類型示例 二、基礎異常捕獲 2.1 簡單異常捕獲語法 2.2 特定異常類型捕獲 三、高級異常處理技術 3.1 完整異常處理語法 3.2 異常傳遞機制 四、主動拋出異常 4.1 自定義異常拋出 4.2 創建自定義異常類 …

基于混沌映射的LDPC信道編譯碼matlab性能仿真,對比LDPC

目錄 1.算法仿真效果 2.算法涉及理論知識概要 2.1 混沌映射 2.2 基于混沌映射的LDPC編譯碼 3.MATLAB核心程序 4.完整算法代碼文件獲得 1.算法仿真效果 matlab2022a仿真結果如下&#xff08;完整代碼運行后無水印&#xff09;&#xff1a; 仿真操作步驟可參考程序配套的操…

學點概率論,打破認識誤區

概率論是統計分析和機器學習的核心。掌握概率論對于理解和開發穩健的模型至關重要&#xff0c;因為數據科學家需要掌握概率論。本博客將帶您了解概率論中的關鍵概念&#xff0c;從集合論的基礎知識到高級貝葉斯推理&#xff0c;并提供詳細的解釋和實際示例。 目錄 簡介 基本集合…

【數據結構_9】棧和隊列

隊列 Queue 一個方向進&#xff0c;一個方向出 Queue隊列提供的核心方法&#xff1a; 入隊列&#xff1a;offer add 出隊列&#xff1a;poll remove 取隊首元素&#xff1a; peek element 前面一列發生錯誤是返回null 后面一列發生錯誤時拋出異常 Queue是否能夠使用isEm…

HarmontOS-ArkUI V2狀態 !!語法糖 雙向綁定

什么是雙向綁定 雙向綁定指的是在組件間數據的雙向綁定。當一個值無論是在父組件還是子組件中改動都會在這兩層中都更新界面。 回顧過往的“雙向綁定”實現方式 靠@Event裝飾回調函數 一般是對于@Param修飾的狀態變量。當子組件發生某個動作的時候,調用某個父組件傳遞過來的…

貪心算法day9(合并區間)

1.合并區間 56. 合并區間 - 力扣&#xff08;LeetCode&#xff09; 對于這種區間問題&#xff0c;我們應該先排序根據排序的結果總結一些規律&#xff0c;進而的得出解決該問題的策略。 class Solution {public static int[][] merge(int[][] intervals) {//第一步進行左端點…

探索加密期權波動率交易的系統化實踐——動態對沖工具使用

Trading Volatility – What Are My Options? 在本文中&#xff0c;我們將介紹一些如何交易資產波動性&#xff08;而非資產價格&#xff09;的示例。為了幫助理解&#xff0c;我們將使用 Deribit 上提供的幾種不同產品&#xff0c;包括但不限于期權。我們將盡可能消除對標的價…

子函數嵌套的意義——以“顏色排序”為例(Python)

多一層縮進精減參數傳遞&#xff0c;參數少平鋪書代碼寫更佳。 筆記模板由python腳本于2025-04-16 11:52:53創建&#xff0c;本篇筆記適合喜歡子函數嵌套結構代碼形式的coder翻閱。 【學習的細節是歡悅的歷程】 博客的核心價值&#xff1a;在于輸出思考與經驗&#xff0c;而不僅…

【數據結構與算法】LeetCode每日一題

此題跟27.移除數組中的指定值 類似&#xff0c;都是移除且雙指針玩法&#xff0c;只不過判斷條件發生了變化 此題跟26.刪除有序數組中的重復項I 一樣&#xff0c;除了fast-1變成了fast-2

c#OleDb連接池管理功能

使用 ConcurrentDictionary 和 ConcurrentBag 來管理數據庫連接 using Drv.Utilities; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Data.OleDb; using System.Linq;namespace Drv.AccessClient {/// <summary>…

【Flink運行時架構】核心組件

在Flink的運行架構中&#xff0c;有兩大比較重要的組件&#xff1a;作業管理器&#xff08;JobManager&#xff09;和任務管理器&#xff08;TaskManager&#xff09;。 Flink的作業提交與任務處理時的系統如下圖所示。 其中&#xff0c;客戶端并不是處理系統的一部分&#xff…

牟乃夏《ArcGIS Engine地理信息系統開發教程》學習筆記2

目錄 一、ArcGIS Engine概述 1、 定義 2、 核心功能 3、 與ArcObjects&#xff08;AO&#xff09;的關系 二、開發環境搭建 1、 開發工具要求 2、 關鍵步驟 三、 ArcGIS Engine核心組件 1、 對象模型 2、 類庫分類 四、 第一個AE應用程序&#xff08;C#示例&#xf…

端、管、云一體化原生安全架構 告別外掛式防護!

面對數字化轉型浪潮&#xff0c;企業網絡安全風險日益凸顯。數據泄露、黑客勒索等事件頻發&#xff0c;合規要求加速推進。盡管企業紛紛部署了防病毒、身份認證、文件加密、入侵防護、流量監控等多種安全系統&#xff0c;但分散且孤立的架構非但沒有有效抵御風險&#xff0c;反…

深度學習--深度學習概念、框架以及構造

文章目錄 一、深度學習1.什么是深度學習&#xff1f;2.特點3.神經網絡構造1&#xff09;.單層神經元2&#xff09;多層神經網絡3&#xff09;小結 4.感知器5.多層感知器6.多層感知器&#xff08;偏置節點&#xff09;7.神經網絡構造 一、深度學習 1.什么是深度學習&#xff1f…