VTK+QT项目:错误LNK1169:找到一个或多个多重定义符号
VTK + QT project: error LNK1169: one or more multiply defined symbols found
我的程序使用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();
}
交互程序样式图像.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
交互程序样式图像.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();
}
对这个问题有什么想法吗?
这很可能是由于vtkStandardNewMacro()。你没有展示你是如何构建这个程序的,但我很确定FluoroViewer最终会出现在一个翻译单元中,而InteractiorStyleImage则会出现在另一个单元中。但是,FluoroViewer#包含定义New函数的InteractiorStyleImage.h。因此,您将在两个独立的对象中使用两个相同的符号,并且链接器会失效。解决方案是将vtkStandardNewMacro()调用行移动到实现(*.cpp文件)中。
HTH,
Miro
相关文章:
- 此代码是否违反一个定义规则
- 静态结构和一个定义规则
- 为什么转换函数声明不需要至少一个定义类型说明符
- 只有一个定义/声明时标头声明变量的多堆定义错误
- 一个定义规则 - 编译
- 为什么传递给函数 set::itrator 而不是 const_iterator 违反了一个定义规则?
- 内联函数和一个定义规则
- 如何在C 中应用ODR(一个定义规则)
- C++ 多个定义,即使只给出了一个定义
- std::integral_constant<T, v>::value 总是有一个定义吗?
- 为什么这不违反一个定义规则
- C 是纯虚拟函数,也是一个定义或仅声明
- 从标准库重新定义函数是否违反了一个定义规则
- 是否使用“ __Date__”或“ __Time__”违反了一个定义规则
- 非静态数据成员和一个定义规则
- 如何在C++中声明一个定义为func(cv::Mat &img)的函数
- 现代C和C :可以将一个定义的结构用于其他声明的结构
- C 是平行阵列一个定义的结构
- 当一个定义位于命名空间中时不明确的函数调用
- C++:同名的文件范围常量违反了一个定义规则