QtDCM编译失败原因咨询:已完成DCMTK/ITK编译仍报错
嘿,你遇到的这些编译错误基本都是QtDCM和你用的DCMTK 3.6.4版本不兼容导致的,和CMake配置关系不大——QtDCM的代码大概率是基于旧版DCMTK写的,而新版DCMTK调整了不少接口。下面逐个给你拆解解决方法:
1. 抽象类实例化失败:QtDcmFindCallback没法创建对象
D:\CPP\qtdcm\src\QtDcmFindScu.cpp(197): error C2259: 'QtDcmFindCallback': cannot instantiate abstract class
note: due to following members: 'void DcmFindSCUCallback::callback(...)': is abstract
这个问题是因为QtDcmFindCallback继承了DCMTK的DcmFindSCUCallback抽象类,但没有正确实现父类要求的纯虚函数callback。你可以这么处理:
- 打开
QtDcmFindScu.h(或者对应的头文件)找到QtDcmFindCallback类 - 对比DCMTK 3.6.4里
DcmFindSCUCallback::callback的签名(在dfindscu.h第96行),确保QtDcmFindCallback里的callback函数参数、返回值完全一致。比如DCMTK里的签名是:virtual void callback(T_DIMSE_C_FindRQ *request, int &responseCount, T_DIMSE_C_FindRSP *response, DcmDataset *responseIdentifiers) = 0; - 如果QtDCM里的函数签名有差异(比如少了某个参数、类型不对),改成和父类完全一样的就行,这样就能解决抽象类无法实例化的问题。
2. 参数类型不匹配:bool转DcmFindSCUExtractMode失败
D:\CPP\qtdcm\src\QtDcmFindScu.cpp(198): error C2664: 'OFCondition DcmFindSCU::performQuery(...)': cannot convert argument 13 from 'bool' to 'DcmFindSCUExtractMode'
DCMTK 3.6.4里performQuery的第13个参数已经从旧版的bool改成了枚举类型DcmFindSCUExtractMode,但QtDCM的代码还在传布尔值。解决方法很简单:
- 找到
QtDcmFindScu.cpp第198行的performQuery调用,把原来的true/false替换成对应的枚举值:- 原来传
true就改成DcmFindSCU::extractAll - 原来传
false就改成DcmFindSCU::extractNone
示例修改:
// 原来的错误调用 scu.performQuery(..., true, ...); // 修改后的正确调用 scu.performQuery(..., DcmFindSCU::extractAll, ...); - 原来传
3. GlobalDcmDataDictionary没有unlock成员
D:\CPP\qtdcm\src\QtDcmMoveScu.cpp(373): error C2039: 'unlock': is not a member of 'GlobalDcmDataDictionary'
DCMTK 3.6.x版本调整了字典的锁机制,旧版的unlock()方法被移除了。你可以这么处理:
- 直接删除
QtDcmMoveScu.cpp第373行的GlobalDcmDataDictionary::unlock();代码 - 如果需要保护字典操作,改用DCMTK新版的RAII风格锁
DcmDataDictionaryLock,示例:// 替换原来的lock/unlock代码块 { DcmDataDictionaryLock lock; // 自动加锁,代码块结束自动解锁 // 原来需要保护的字典操作代码 }
4. DU_findSOPClassAndInstanceInDataSet参数数量不匹配
D:\CPP\qtdcm\src\QtDcmMoveScu.cpp(775): error C2660: 'DU_findSOPClassAndInstanceInDataSet': function does not take 4 arguments
DCMTK 3.6.4更新了这个函数的签名,参数数量减少了。查看diutil.h里的正确签名:
OFCondition DU_findSOPClassAndInstanceInDataSet(DcmItem *dataset, OFString &sopClassUID, OFString &sopInstanceUID, const OFBool searchIntoSub = OFFalse);
你需要修改QtDCM里的调用:
- 去掉多余的参数,或者根据需求补充最后一个可选参数(默认是
OFFalse)
示例修改:// 原来的错误调用 DU_findSOPClassAndInstanceInDataSet(ds, classUID, instUID, extraParam); // 修改后的正确调用(不需要搜索子数据集) DU_findSOPClassAndInstanceInDataSet(ds, classUID, instUID); // 或者需要搜索子数据集时 DU_findSOPClassAndInstanceInDataSet(ds, classUID, instUID, OFTrue);
5. ASC_getAPTitles参数数量不匹配
D:\CPP\qtdcm\src\QtDcmMoveScu.cpp(965): error C2660: 'ASC_getAPTitles': function does not take 4 arguments
同样是DCMTK版本升级后的接口变化,查看assoc.h里的正确签名:
OFCondition ASC_getAPTitles(ASC_Association *assoc, OFString &ourTitle, OFString &theirTitle);
你只需要修改QtDCM里的调用,去掉多余的两个参数即可:
// 原来的错误调用 ASC_getAPTitles(assoc, ourTitle, theirTitle, param1, param2); // 修改后的正确调用 ASC_getAPTitles(assoc, ourTitle, theirTitle);
你有两个选择可以解决问题:
- 按照上面的步骤手动修改QtDCM的源码,适配DCMTK 3.6.4的新接口;
- 下载和QtDCM兼容的旧版DCMTK(比如3.6.0或更早版本),重新编译后再编译QtDCM。
内容的提问来源于stack exchange,提问作者Dogrtt

