【问题标题】:VTK + QT project: error LNK1169: one or more multiply defined symbols foundVTK + QT 项目:错误 LNK1169:找到一个或多个多重定义符号
【发布时间】:2016-01-07 22:09:20
【问题描述】:

我的程序正在使用 VTK 和 QT 在 QT 窗口内创建一个 DICOM 查看器。我正在尝试设置一个自定义交互器,以便我可以覆盖输入函数。创建此自定义交互器类后,我遇到了链接器错误。我的代码如下:

FluoroViewer.h:

#ifndef FluoroViewer_H
#define FluoroViewer_H

#include <QMainWindow>

#include <vtkSmartPointer.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkDICOMImageReader.h>
#include <vtkImageViewer2.h>

#include "InteractorStyleImage.h"

namespace Ui {
    class FluoroViewer;
}

class FluoroViewer : public QMainWindow {
    Q_OBJECT

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

    private slots:
        void openDICOMFolder();
        void on_loadImages_clicked();

    private:
        Ui::FluoroViewer *ui;
        void drawDICOMSeries(std::string folderDICOM);
        vtkSmartPointer<vtkDICOMImageReader> readerDICOMSeries;
        vtkSmartPointer<vtkImageViewer2> imageViewerDICOMSeries;
        vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor;
        vtkSmartPointer<InteractorStyleImage> interactorStyle;
};

#endif

FluoroViewer.cxx:

#include "FluoroViewer.h"
#include "ui_FluoroViewer.h"

#include <QFileDialog>

FluoroViewer::FluoroViewer(QWidget *parent) : QMainWindow(parent), ui(new Ui::FluoroViewer) {
    ui->setupUi(this);
    readerDICOMSeries = vtkSmartPointer<vtkDICOMImageReader>::New();
    imageViewerDICOMSeries = vtkSmartPointer<vtkImageViewer2>::New();
    renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
    //interactorStyle = vtkSmartPointer<InteractorStyleImage>::New();
}

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

void FluoroViewer::openDICOMFolder() {
    QString folderNameDICOM = QFileDialog::getExistingDirectory(this, tr("Open DICOM Folder"), QDir::currentPath(), QFileDialog::ShowDirsOnly);
    std::string folderName = folderNameDICOM.toUtf8().constData();
    drawDICOMSeries(folderName);
}

void FluoroViewer::drawDICOMSeries(std::string folderDICOM) {
    readerDICOMSeries->SetDirectoryName(folderDICOM.c_str());
    readerDICOMSeries->Update();

    imageViewerDICOMSeries->SetInputConnection(readerDICOMSeries->GetOutputPort());

    ui->slider->setMinimum(imageViewerDICOMSeries->GetSliceMin());
    ui->slider->setMaximum(imageViewerDICOMSeries->GetSliceMax());

    //interactorStyle->SetImageViewer(imageViewerDICOMSeries);

    imageViewerDICOMSeries->SetupInteractor(renderWindowInteractor);
    //renderWindowInteractor->SetInteractorStyle(interactorStyle);

    // SET FLUORO COLOR AND WINDOW LEVELS
    imageViewerDICOMSeries->SetColorLevel(523);
    imageViewerDICOMSeries->SetColorWindow(-1223);

    imageViewerDICOMSeries->SetRenderWindow(ui->vtkRenderer->GetRenderWindow());
    imageViewerDICOMSeries->Render();
    renderWindowInteractor->Disable();
    renderWindowInteractor->Start();
}

void FluoroViewer::on_loadImages_clicked() {
    openDICOMFolder();
}

InteractorStyleImage.h:

#ifndef InteractorStyleImage_H
#define InteractorStyleImage_H

#include <vtkSmartPointer.h>
#include <vtkObjectFactory.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkImageViewer2.h>
#include <vtkDICOMImageReader.h>
#include <vtkInteractorStyleImage.h>

class InteractorStyleImage : public vtkInteractorStyleImage {
    public:
        static InteractorStyleImage* New();
        vtkTypeMacro(InteractorStyleImage, vtkInteractorStyleImage);

    protected:
        vtkImageViewer2* imageViewer;
        int currentSlice;
        int minSlice;
        int maxSlice;

    public:
        void SetImageViewer(vtkImageViewer2* imageViewerTemp);
        void MoveSliceForward();
        void MoveSliceBackward();

    public:
        virtual void OnKeyDown() {
            std::string key = this->GetInteractor()->GetKeySym();
            if (key.compare("Up") == 0) {
                cout << "Up arrow key was pressed." << endl;
                MoveSliceForward();
            }
            else if (key.compare("Down") == 0) {
                cout << "Down arrow key was pressed." << endl;
                MoveSliceBackward();
            }
            vtkInteractorStyleImage::OnKeyDown();
        }

    public:
        virtual void OnMouseWheelForward() {
            cout << "Scrolled mouse wheel forward." << endl;
            MoveSliceForward();
            //vtkInteractorStyleImage::OnMouseWheelForward();
        }

    public:
        virtual void OnMouseWheelBackward() {
            cout << "Scrolled mouse wheel backward." << endl;
            if (currentSlice > minSlice) {
                MoveSliceBackward();
            }
            //vtkInteractorStyleImage::OnMouseWheelBackward();
        }
};
vtkStandardNewMacro(InteractorStyleImage);

#endif

InteractorStyleImage.cxx:

#include "InteractorStyleImage.h"

void InteractorStyleImage::SetImageViewer(vtkImageViewer2* imageViewerTemp) {
    imageViewer = imageViewerTemp;
    minSlice = imageViewer->GetSliceMin();
    maxSlice = imageViewer->GetSliceMax();
    currentSlice = minSlice;
    cout << "Slicer: Min = " << minSlice << ", Max = " << maxSlice;
}

void InteractorStyleImage::MoveSliceForward() {
    if(currentSlice < maxSlice) {
        currentSlice += 1;
        imageViewer->SetSlice(currentSlice);
        imageViewer->Render();
    }
}

void InteractorStyleImage::MoveSliceBackward() {
    if(currentSlice > minSlice) {
        currentSlice -= 1;
        imageViewer->SetSlice(currentSlice);
        imageViewer->Render();
    }
}

FluoroViewerDriver.cxx:

#include <QApplication>
#include "FluoroViewer.h"

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    FluoroViewer fluoroViewer;
    fluoroViewer.show();

    return app.exec();
}

对这个问题有什么想法吗?

【问题讨论】:

  • 你在什么系统上?什么编译器? VTK版本? Qt版本?最重要的是,确切的链接器消息是什么? -- 多重定义符号是什么?
  • 使用 Visual Studio 2013、VTK 6.3.0、QT 5.5 在 Windows 10 64 位上运行,确切消息是:错误 LNK1169:找到一个或多个多重定义符号 C:\Users\BBL\Desktop \ML Thesis\FluoroViewer\bin\Release\FluoroViewer.exe AND LNK2005: "public: static class InteractorStyleImage * __cdecl InteractorStyleImage::New(void)" (?New@InteractorStyleImage@@SAPEAV1@XZ) 已在 FluoroViewer.obj C 中定义:\Users\BBL\Desktop\ML Thesis\FluoroViewer\bin\FluoroViewerDriver.obj

标签: c++ visual-studio qt linker-errors vtk


【解决方案1】:

这很可能是由于 vtkStandardNewMacro()。 你没有展示你是如何构建这个程序的,但我很确定 FluoroViewer 最终会出现在一个翻译单元中,而 InteractorStyleImage 会出现在另一个翻译单元中。但是,FluoroViewer #includes InteractorStyleImage.h,它定义了 New 函数。因此,您最终会在两个单独的对象中得到两个相同的符号,并且链接器会出错。解决方案是将 vtkStandardNewMacro() 调用行移到实现中(*.cpp 文件)。

HTH,

米罗

【讨论】:

  • 这成功了!感谢您的帮助和明确的解释! :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多