Qt为架构x86_64找到重复的符号

时间:2017-10-22 03:13:20

标签: c++ qt

我有一个名为Segmentation的名称空间segmentation.h的头文件。标头中声明的函数在实现文件segmentation.cpp中定义。命名空间在mainwindow.cpp中使用,因此它已包含在所述文件中。但是当我尝试编译项目时,我得到了

  

1 duplicate symbols found for architecture x86_64

我确实理解当您尝试在链接期间多次包含模块时会发生duplicate symbols found for architecture x86_64错误。但我在上述文件中只包含segmentation.h一次。

segmentation.h

#ifndef SEGMENTATION_H
#define SEGMENTATION_H

#include <QObject>
#include <opencv2/opencv.hpp>
#include <QPixmap>

namespace Segmentation
{
    int k;
    cv::Mat getSegments(cv::Mat inputImage);
    cv::Mat sampleInput(cv::Mat &inputImage);
}

#endif // SEGMENTATION_H

segmentation.cpp

#include "segmentation.h"
#include <opencv2/opencv.hpp>
#include <iostream>

cv::Mat Segmentation::getSegments(cv::Mat inputImage)
{

    Segmentation::sampleInput(inputImage);

    //Incomplete code

    return inputImage;
}

cv::Mat Segmentation::sampleInput(cv::Mat &inputImage)
{
    std::cout << "Size: " << inputImage.size << std::endl;
    std::cout << "Rows: " << inputImage.rows << std::endl;
    std::cout << "Cols: " << inputImage.cols << std::endl;
    std::cout << "Size rows x cols: " << inputImage.rows * inputImage.cols << std::endl;

    //Incomplete code

    return inputImage;
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QPixmap>
#include <QGraphicsView>
#include <QLabel>
#include <QGraphicsScene>
#include <QGraphicsPixmapItem>
#include <opencv2/opencv.hpp>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void on_loadImageButton_clicked();
    void on_clearScreenButton_clicked();
    void on_segmentButton_clicked();

private:
    Ui::MainWindow *ui;
    cv::Mat _rawInputImage;
    QPixmap _inputImage;
    QPixmap _outputImage;
    QGraphicsScene _scene;
    QGraphicsPixmapItem _inputImagePixmapItem;

};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>
#include <QString>
#include <QDebug>
#include <QRectF>
#include <segmentation.h>

MainWindow::MainWindow(QWidget *parent):QMainWindow(parent),ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    MainWindow::setWindowState(Qt::WindowFullScreen);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_loadImageButton_clicked()
{
    QFileDialog fileDialog(this, Qt::Dialog);
    fileDialog.setFileMode(QFileDialog::ExistingFile);
    fileDialog.setNameFilter("*.jpg *.png *.jpeg");
    fileDialog.setViewMode(QFileDialog::Detail);
    fileDialog.exec();

    QStringList selectedFileName = fileDialog.selectedFiles();
    QString selectedFile = selectedFileName.at(0);
    _inputImage.load(selectedFile);
    _rawInputImage = cv::imread(selectedFile.toStdString());

    _inputImagePixmapItem.setPixmap((_inputImage));
    _scene.addItem(&_inputImagePixmapItem);
    this->ui->inputImageViewWidget->setScene(&_scene);
    this->ui->inputImageViewWidget->fitInView(&_inputImagePixmapItem, Qt::KeepAspectRatio);

    fileDialog.saveState();
    return;
}

void MainWindow::on_clearScreenButton_clicked()
{
    _scene.removeItem(&_inputImagePixmapItem);
    return;
}

void MainWindow::on_segmentButton_clicked()
{
    cv::Mat segmentedOutputImage = Segmentation::getSegments(_rawInputImage);
}

编译输出

14:15:59: Running steps for project LaundroBotQt...
14:15:59: Configuration unchanged, skipping qmake step.
14:15:59: Starting: "/usr/bin/make" 
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -headerpad_max_install_names -stdlib=libc++ -Wl,-syslibroot,/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk -mmacosx-version-min=10.9  -Wl,-rpath,/Users/Vino/Documents/Qt/5.8/clang_64/lib -o LaundroBotQt.app/Contents/MacOS/LaundroBotQt main.o mainwindow.o segmentation.o moc_mainwindow.o   -F/Users/Vino/Documents/Qt/5.8/clang_64/lib -L/usr/local/lib -lopencv_core -lopencv_imgcodecs -lopencv_highgui -lopencv_features2d -lopencv_ml -lopencv_flann -lopencv_imgproc -lopencv_photo -framework QtWidgets -framework QtGui -framework QtCore -framework DiskArbitration -framework IOKit -framework OpenGL -framework AGL 
duplicate symbol __ZN12Segmentation1kE in:
    mainwindow.o
    segmentation.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [LaundroBotQt.app/Contents/MacOS/LaundroBotQt] Error 1
14:15:59: The process "/usr/bin/make" exited with code 2.
Error while building/deploying project LaundroBotQt (kit: Desktop Qt 5.8.0 clang 64bit)
When executing step "Make"
14:15:59: Elapsed time: 00:01.

GitHub repo link

我不太确定如何解决这个问题。我已阅读StackOverflow,但我的问题似乎很奇怪。任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:1)

问题在于,在segmentation.h中:

namespace Segmentation
{
   int k;
   [...]

在此,您既可以在Segmentation命名空间中为名为k的变量声明和定义存储。问题是,如果有多个.cpp文件#include的segmentation.h(几乎肯定会发生),那么变量Segmentation :: k将在多个.cpp文件中为它声明存储空间,导致你看到的重复符号错误。

要解决这个问题,请在segmentation.h中执行此操作:

namespace Segmentation
{
   extern int k;
   [...]

...然后在你的一个.cpp文件中(可能是segmentation.cpp最合适的一个),单独添加存储,如下所示:

namespace Segmentation
{
   int k;
};

这样,Segmentation :: k的存储空间将只分配给那个.cpp文件而不是其中的很多。