这不是最令人烦恼的解析问题,因为执行以下操作也会导致链接器错误,尽管没有歧义:
QImage baseline("C:\img1.png");
QImage test_image("C:\img1.png");
我的应用程序获得2个命令行参数,这些参数是2个不同图像的路径。
我想将它们转换为QImage,因此我可以使用Qt提供的==
运算符对它们进行比较。
我尝试了以下方法来解决这个问题,但每次都会遇到链接器问题:
尝试1:
QImage baseline(argv[1]);
QImage test_image(argv[2]);
尝试2(首先转换为Qstring):
QString base_path = QString::fromStdString(argv[1]);
QString test_path = QString::fromStdString(argv[2]);
QDir baseline(base_path);
QDir test_image(test_path);
我认为这与没有包含正确的库有关,因为如果我只是执行以下操作,程序将编译并链接正常:
Qimage test_image();
已经看过下面的帖子,遗憾的是在我的情况下它没有用处: Constructing QImage from unsigned char* data
有关可能导致链接器错误的任何想法?我怀疑他们会非常有帮助,但我会在这里留下链接器错误消息:
Severity Code Description Project File Line Suppression State Error LNK2019 unresolved external symbol "__declspec(dllimport) public: __thiscall QString::~QString(void)" (__imp_??1QString@@QAE@XZ) referenced in function _main image_compare_executable c:\Users\gela8178\documents\visual studio 2015\Projects\image_compare_executable\image_compare_executable\image_compare_executable.obj
1 Error LNK2019 unresolved external symbol "__declspec(dllimport) public: static class QString __cdecl QString::fromStdString(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (__imp_?fromStdString@QString@@SA?AV1@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) referenced in function _main image_compare_executable c:\Users\gela8178\documents\visual studio 2015\Projects\image_compare_executable\image_compare_executable\image_compare_executable.obj
1 Error LNK1120 2 unresolved externals image_compare_executable c:\users\gela8178\documents\visual studio 2015\Projects\image_compare_executable\Debug\image_compare_executable.exe 1
包含导致链接器问题的代码的相关片段:
#include "stdafx.h"
#include <iostream>
#include <opencv2/opencv.hpp>
#include <QtGui/QtGui>
using namespace cv;
int main(int argc, char* argv[])
{
// Check the number of parameters
if (argc < 3) {
std::cerr << "Error: " << argv[0] << " : " << "Missing arguments" << std::endl;
return 1;
}
std::cout << "Baseline: " << argv[1] << "\n" << "Test Image: " << argv[2] << std::endl;
QImage baseline(QString(argv[1]));
QImage test_image(QString(argv[2]));
if (baseline == test_image)
{
std::cout << "Algorithm: Mem Compare" << "\n" << "Result: = Pass" << std::endl;
}
else
{
std::cout << "Algorithm: Mem Compare" << "\n" << "Result: = Fail" << std::endl;
}
std::cout << "--------------------------------------------------------" << std::endl;
// ***************************************************************************** //
//Run MSSIM and output tuple
Mat i1 = imread(argv[1]);
Mat i2 = imread(argv[2]);
Scalar min_ssim = getMSSIM(i1, i2);
double R = min_ssim[0];
double G = min_ssim[1];
double B = min_ssim[2];
std::cout << "Algorithm: MSSIM" << "\n" << "Result: " << "(" << R << ", " << G << ", " << B << ")" << std::endl;
std::cout << "--------------------------------------------------------" << std::endl;
return 0;
}
SOLUTION:
查看QImage构造函数here,获取QString的唯一实例将其作为const reference
:
QImage(const QString &fileName, const char *format = Q_NULLPTR)
执行以下操作
QImage baseline(QString(argv[1]));
正在抛出链接器错误,因为QString是由r引用传递的,在QImage尝试访问时被销毁。所以可能的修复方法是分别进行QString赋值,然后将其传递给QImage,这样就可以了:
QImage baseline(argv[1]);
QImage test_image(argv[2]);
答案 0 :(得分:0)
首先,QImage baseline(QString(argv[1]))
是一个最令人烦恼的解析。期。您正在使用不会向您发出警告的编译器。 (argv[1])
周围的括号是多余的。该声明的规范形式为:
QImage baseline(QString [1]);
您也不应该使用argv
,因为它不可移植。例如,在Windows上,argv
是垃圾。
改为使用QCoreApplication::arguments()
:
int main(int argc, char ** argv) {
QGuiApplication app{argc, argv};
auto const args = app.arguments();
if (args.count() < 3)
return 1;
QImage baseline(args[1]);
QImage test_image(args[2]);
//...
}
如果你从一开始就使用它,你甚至不会遇到你遇到的问题。因此,您可以看到它们的好处是双重的:它可以保护您免受最棘手的解析,和它在Windows上正常工作:)
当然,如果您有基于小部件的Ui,也可以使用QApplication
。但对于QImage
,您只需要QGuiApplication
。
常见Qt方法/构造函数的链接器错误(例如__declspec(dllimport) public: __thiscall QString::~QString(void)
表示您未将项目与Qt链接。
如果您已经在使用qmake,那么只有在您未将#include <QtGui/QtGui>
模块添加到项目中时才需要gui
。正确的形式是#include <QtGui>
。如果编译器抱怨它无法找到该文件,则您无法将项目设置为正确使用Qt。一旦你这样做,文件应该编译和链接 - 再次,假设你使用qmake或cmake和Qt宏。