在 Qt 项目中链接第三方库 (DCMTK)





0/5 (0投票)
本文演示了如何将第三方库 (DCMTK) 链接到基于 Qt 的项目中。
引言
本文演示了如何正确地将第三方库链接到基于 Qt 的项目中。Qt 是一个广泛使用的跨平台 C++ 框架。我们将使用 Qt Creator 开发一个简单的基于控制台的应用程序,并链接 DCMTK 库来读取 DICOM 文件并显示其内容。DCMTK 是一个广泛用于处理 DICOM 图像的库。
背景
本文假设您已经熟悉 DICOM (Digital Imaging and Communications in Medicine) 协议、DCMTK 库和 Qt。有关这些内容的更多信息,请使用以下链接:
http://dicom.offis.de/dcmtk.php.en http://dicom.nema.org/ https://www.qt.io/developers/入门
请确保您已具备以下先决条件:
- 已按照 DCMTK 主页上的说明构建 DCMTK 库。
- Qt Creator (我使用的是 3.6 版本)
本文项目使用的所有源代码都可以通过上面的下载链接下载。
项目结构
在名为 DcmtkQtLink 的根目录下,有以下子目录和文件:
- main.cpp
- MyQtApp.pro
- thirdparty/dcmtk
- resources
"main.cpp" 是主程序入口文件。"MyQtapp.pro" 是在 Qt Creator 中创建的项目文件,其中包含 qmake 用于构建我们项目的脚本。子目录 "thirdparty/dcmtk" 包含预编译的库、dll 和头文件。本文中仅包含运行应用程序所需的必要库、dll 和头文件。"resources" 文件夹包含一个将在应用程序中使用的 DICOM 文件示例。
构建项目
下载源代码后,请按照以下说明构建项目:
- 只需在 Qt Creator IDE 中打开 MyQtApp.pro 文件。
- 在模式选择器中,选择“Projects”。在“Edit build configuration”(编辑构建配置)中,选择构建配置模式。在“Build directory”(构建目录)中,选择“Browse”(浏览)导航到应用程序代码文件夹。例如:C:\qt\DcmtkQtLink
- 在“Build Steps”(构建步骤)中,点击“Add Build Step”(添加构建步骤)。这将弹出一个带有默认值的表单。保留默认值,并在“Make arguments:”中输入“install”。此步骤将确保必要的库和 Dll 文件被复制到生成 .exe 文件的文件夹中。
- 选择“Build”(构建)和“Run qmake”(运行 qmake)。
- 点击“Build”(构建)按钮来构建项目。
- 点击“Run”(运行)按钮来运行项目。
使用代码
本节介绍代码的工作原理。
首先,让我们看看项目文件 "MyQtApp.pro",因为它是 Qt Creator 用于成功构建应用程序的主要文件。如果您需要关于 qmake 项目文件的基本教程,请参阅 https://doc.qt.ac.cn/qt-4.8/qmake-project-files.html。
// MyQtApp.pro
QT += core
QT -= gui
CONFIG += c++11
TARGET = MyQtApp
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp
INCLUDEPATH += $$PWD/thirdparty/dcmtk/include
DEPENDPATH += $$PWD/thirdparty/dcmtk/include
win32:CONFIG(debug,debug|release): LIBS += -L$$PWD/thirdparty/dcmtk/lib/ -ldcmdatad -ldcmimgled -ldcmimaged -ldcmjplsd -loflogd -lofstdd -ldcmjpegd
win32:CONFIG(release,debug|release): LIBS += -L$$PWD/thirdparty/dcmtk/lib/ -ldcmdata -ldcmimgle -ldcmimage -ldcmjpls -loflog -lofstd -ldcmjpeg
win32:CONFIG(debug,debug|release): DESTDIR = bin/debug
else:win32:CONFIG(release,release|debug) : DESTDIR = bin/release
win32{
CONFIG(debug,debug|release) {
dlls_to_move.path = $$DESTDIR
dlls_to_move.files += $$PWD/thirdparty/dcmtk/bin/dcmdatad.dll
dlls_to_move.files += $$PWD/thirdparty/dcmtk/bin/dcmimgled.dll
dlls_to_move.files += $$PWD/thirdparty/dcmtk/bin/dcmimaged.dll
dlls_to_move.files += $$PWD/thirdparty/dcmtk/bin/dcmjplsd.dll
dlls_to_move.files += $$PWD/thirdparty/dcmtk/bin/oflogd.dll
dlls_to_move.files += $$PWD/thirdparty/dcmtk/bin/ofstdd.dll
dlls_to_move.files += $$PWD/thirdparty/dcmtk/bin/dcmjpegd.dll
INSTALLS += dlls_to_move
}
else {
dlls_to_move.path = $$DESTDIR
dlls_to_move.files += $$PWD/thirdparty/dcmtk/bin/dcmdata.dll
dlls_to_move.files += $$PWD/thirdparty/dcmtk/bin/dcmimgle.dll
dlls_to_move.files += $$PWD/thirdparty/dcmtk/bin/dcmimage.dll
dlls_to_move.files += $$PWD/thirdparty/dcmtk/bin/dcmjpls.dll
dlls_to_move.files += $$PWD/thirdparty/dcmtk/bin/oflog.dll
dlls_to_move.files += $$PWD/thirdparty/dcmtk/bin/ofstd.dll
dlls_to_move.files += $$PWD/thirdparty/dcmtk/bin/dcmjpeg.dll
INSTALLS += dlls_to_move
}
# copy resources
resources_to_move.path = $$DESTDIR
resources_to_move.files += $$PWD/resources/dicom_testdata.dcm
INSTALLS += resources_to_move
}
QT += core 和 QT += gui 是 Qt 特定的配置选项。CONFIG += c++11 是一个通用的项目配置选项,它告诉 qmake 我们正在使用 C++11 功能。其他 CONFIG 参数定义这是一个基于控制台的应用程序。
我们只有一个源文件,添加到 SOURCES 变量中,如 SOURCES += main.cpp。
为了能够在我们的源代码中包含头文件,我们必须按如下方式包含路径和依赖路径:
INCLUDEPATH += $$PWD/thirdparty/dcmtk/include
DEPENDPATH += $$PWD/thirdparty/dcmtk/include
接下来,我们添加将要使用的 DCMTK 的实际库文件 (.lib)。请注意,库文件有两种版本。一种是调试模式下编译的(库名称末尾带有 d 后缀),另一种是发布模式下编译的。
win32:CONFIG(debug,debug|release): LIBS += -L$$PWD/thirdparty/dcmtk/lib/ -ldcmdatad -ldcmimgled -ldcmimaged -ldcmjplsd -loflogd -lofstdd -ldcmjpegd
win32:CONFIG(release,debug|release): LIBS += -L$$PWD/thirdparty/dcmtk/lib/ -ldcmdata -ldcmimgle -ldcmimage -ldcmjpls -loflog -lofstd -ldcmjpeg
当项目构建时,会创建许多中间文件和最终的可执行文件。如果我们想在源文件目录之外创建这些文件,我们可以添加以下代码,通过使用 DESTDIR 变量来定义我们的目标目录路径。同样,这会为调试和发布配置分别设置。此步骤对于稍后告诉 'qmake' 将必要的 DLL 文件和测试数据复制到最终可执行文件所在的文件夹也非常重要。
win32:CONFIG(debug,debug|release): DESTDIR = bin/debug
else:win32:CONFIG(release,release|debug) : DESTDIR = bin/release
最后,由于我们在此应用程序中静态链接 DCMTK,因此必须在可执行文件所在的文件夹中放置必要的 DLL 文件。为此,我们添加以下脚本,它只是将 thirdparty/dcmtk 目录中的调试/发布版本的 DLL 文件复制到我们之前指定的 DESTDIR 路径。这是通过首先分配 DLL 文件所在的相对路径,然后使用 INSTALL 变量作为构建后操作执行实际复制操作来完成的。这里需要注意的是,为了使此脚本生效,我们必须调用 qmake install。而且,我们已经在“构建项目”部分的步骤 3 中完成了此操作。
此外,我们还可以使用 INSTALL 变量复制位于“resource”文件夹中的文件(我们的 DICOM 测试文件样本)。
win32{
CONFIG(debug,debug|release) {
dlls_to_move.path = $$DESTDIR
dlls_to_move.files += $$PWD/thirdparty/dcmtk/bin/dcmdatad.dll
dlls_to_move.files += $$PWD/thirdparty/dcmtk/bin/dcmimgled.dll
dlls_to_move.files += $$PWD/thirdparty/dcmtk/bin/dcmimaged.dll
dlls_to_move.files += $$PWD/thirdparty/dcmtk/bin/dcmjplsd.dll
dlls_to_move.files += $$PWD/thirdparty/dcmtk/bin/oflogd.dll
dlls_to_move.files += $$PWD/thirdparty/dcmtk/bin/ofstdd.dll
dlls_to_move.files += $$PWD/thirdparty/dcmtk/bin/dcmjpegd.dll
INSTALLS += dlls_to_move
}
else {
dlls_to_move.path = $$DESTDIR
dlls_to_move.files += $$PWD/thirdparty/dcmtk/bin/dcmdata.dll
dlls_to_move.files += $$PWD/thirdparty/dcmtk/bin/dcmimgle.dll
dlls_to_move.files += $$PWD/thirdparty/dcmtk/bin/dcmimage.dll
dlls_to_move.files += $$PWD/thirdparty/dcmtk/bin/dcmjpls.dll
dlls_to_move.files += $$PWD/thirdparty/dcmtk/bin/oflog.dll
dlls_to_move.files += $$PWD/thirdparty/dcmtk/bin/ofstd.dll
dlls_to_move.files += $$PWD/thirdparty/dcmtk/bin/dcmjpeg.dll
INSTALLS += dlls_to_move
}
# copy resources
resources_to_move.path = $$DESTDIR
resources_to_move.files += $$PWD/resources/dicom_testdata.dcm
INSTALLS += resources_to_move
}
其次,我们查看 "main.cpp" 文件。
// main.cpp
#include <QCoreApplication>
#include <QDebug>
// DCMTK includes
#include <dcmtk/dcmdata/dcfilefo.h>
#include <dcmtk/dcmdata/dcdeftag.h>
// STL includes
#include <memory>
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
qDebug() << "**********************************************\n";
qDebug() << "Demo - linking DCMTK library to QT project";
qDebug() << "**********************************************\n";
// get the test data to load
QString test_data_file_name = "/dicom_testdata.dcm";
QString test_data_file_path = QCoreApplication::applicationDirPath() + test_data_file_name;
qDebug() << "\nTest data file path: \n" << test_data_file_path << "\n";
DcmFileFormat file_format;
OFCondition status = file_format.loadFile(test_data_file_path.toStdString().c_str());
std::shared_ptr<DcmDataset> dataset(file_format.getDataset());
qDebug() << "\nInformation extracted from DICOM file: \n";
const char* buffer = nullptr;
DcmTagKey key = DCM_PatientName;
dataset->findAndGetString(key,buffer);
std::string tag_value = buffer;
qDebug() << "Patient name: " << tag_value.c_str();
key = DCM_PatientID;
dataset->findAndGetString(key,buffer);
tag_value = buffer;
qDebug() << "Patient id: " << tag_value.c_str();
key = DCM_TransferSyntaxUID;
dataset->findAndGetString(key,buffer);
if(buffer == NULL) {
qDebug() << "Transfer syntax value is NULL";;
}
else {
tag_value = buffer;
qDebug() << "Transfer syntax: " << tag_value.c_str();
}
E_TransferSyntax transfer_syntax = dataset->getCurrentXfer();
DcmXfer dcm_ts(transfer_syntax);
std::string ts_name = dcm_ts.getXferName();
qDebug() << "Transfer syntax name: " << ts_name.c_str();
return app.exec();
}
该文件包含来自 DCMTK 的必要头文件,如下所示:
#include <dcmtk/dcmdata/dcfilefo.h>
#include <dcmtk/dcmdata/dcdeftag.h>
我们可以通过使用以下代码获取已复制到 .exe 文件所在文件夹的测试 DICOM 文件(作为构建后步骤):
QString test_data_file_name = "/dicom_testdata.dcm";
QString test_data_file_path = QCoreApplication::applicationDirPath() + test_data_file_name;
输出
********************************************** Demo - linking DCMTK library to QT project ********************************************** Test data file path: "C:/p/qt/ext_lib_link_demo/tutorial/MyQtApp/bin/debug/dicom_testdata.dcm" Information extracted from DICOM file: Patient name: PELVIX Patient id: Vafm7b0J Transfer syntax value is NULL Transfer syntax name: JPEG 2000 (Lossless or Lossy)
历史
- 2016-06-06: 首次发布
在此处保持您所做的任何更改或改进的实时更新。