This question already has answers here:
multiple definition of namespace variable, C++ compilation

(3个答案)


3年前关闭。




我有一个名为Segmentation的 namespace segmentation.h的头文件。 header 中声明的功能在实现文件segmentation.cpp中定义。 namespace 在mainwindow.cpp中使用,因此已包含在所述文件中。但是当我尝试编译项目时,我得到



我确实理解duplicate symbols found for architecture x86_64错误,当您在链接期间尝试多次包含一个模块时会发生。但是我在上述文件中只包含一次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

分段
#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;
}

主窗口
#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

主窗口
#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,但我的问题似乎很奇怪。任何帮助表示赞赏。

最佳答案

问题在这里,在segmentation.h中:

namespace Segmentation
{
   int k;
   [...]

在这里,您既要声明也要定义Segmentation namespace 中名为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文件中分配,而不是在其中的许多文件中分配。

关于c++ - 找到针对架构x86_64的Qt重复符号,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46870131/

10-13 06:02