未解析的外部符号

C++ error LNK2001: unresolved external symbol

本文关键字:外部 符号      更新时间:2023-10-16

我在我的项目中有一个编译问题。我读过很多标题上有这个错误的帖子,但我无法修复它。

我收到这个错误:

Error   4   error LNK2019: unresolved external symbol "public: class vtkUnstructuredGrid * __thiscall volumerendering::volume(class itk::SmartPointer<class itk::Image<unsigned short,3> >,class itk::SmartPointer<class itk::Image<int,3> >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?volume@volumerendering@@QAEPAVvtkUnstructuredGrid@@V?$SmartPointer@V?$Image@G$02@itk@@@itk@@V?$SmartPointer@V?$Image@H$02@itk@@@4@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) referenced in function __catch$_main$0 a.obj
Error   5   fatal error LNK1120: 1 unresolved externals C:UsersSERAPDesktopprogramlarvnewbDebugDICOM.exe

代码如下:

a.cpp

  #if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif
#ifdef __BORLANDC__
#define ITK_LEAN_AND_MEAN
#endif
#include "volumerendering.h"
#include "itkImage.h"
#include "itkImageSeriesReader.h"
#include "itkImageFileWriter.h"
#include "itkNumericSeriesFileNames.h"
#include "itkPNGImageIO.h"
#include "itkTIFFImageIO.h"
#include <vtkXMLUnstructuredGridWriter.h>
// Software Guide : EndCodeSnippet
#include <list>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include<itkRGBPixel.h>
#include "itkThresholdImageFilter.h"
#include "itkGDCMSeriesFileNames.h"
#include "itkGDCMImageIO.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkSmartPointer.h"
#include "vtkImageActor.h"
#include "vtkInteractorStyleImage.h"
#include "vtkRenderer.h"
#include"vtkImageViewer2.h"
#include <vtkSliderWidget.h>
#include <vtkSliderRepresentation2D.h>
#include <vtkSTLWriter.h>
// Software Guide : EndCodeSnippet

int main( int argc, char ** argv )
{
  // Verify the number of parameters in the command line
  if( argc < 6 )
    {
    std::cerr << "Usage: " << std::endl;
    std::cerr << argv[0] << " firstSliceValue lastSliceValue  outputImageFile OrjinalDicomDirectory Alanhesabı(txt)DosyasıAdı" << std::endl;
    return EXIT_FAILURE;
    }
  typedef    unsigned short                   PixelType;
  const unsigned int Dimension = 3;
  typedef itk::Image< PixelType, Dimension >  ImageType;
  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // The image type is used as a template parameter to instantiate
  // the reader and writer.
  //
  // index{itk::ImageSeriesReader!Instantiation}
  // index{itk::ImageFileWriter!Instantiation}
  //
  // Software Guide : EndLatex 
  // Software Guide : BeginCodeSnippet
  typedef itk::ImageSeriesReader< ImageType >  ReaderType;
  ReaderType::Pointer reader = ReaderType::New();
  const unsigned int first = atoi( argv[1] );
  const unsigned int last  = atoi( argv[2] );
  typedef itk::NumericSeriesFileNames    NameGeneratorType;
  NameGeneratorType::Pointer nameGenerator = NameGeneratorType::New();
  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // The filenames generator requires us to provide a pattern of text for the
  // filenames, and numbers for the initial value, last value and increment to be
  // used for generating the names of the files.
  //
  // Software Guide : EndLatex 
  // Software Guide : BeginCodeSnippet
  nameGenerator->SetSeriesFormat( "trabekuler%03d.tiff" );
  nameGenerator->SetStartIndex( first );
  nameGenerator->SetEndIndex( last );
  nameGenerator->SetIncrementIndex( 1 );
  reader->SetImageIO( itk::TIFFImageIO::New() );
  //reader->SetImageIO( itk::PNGImageIO::New() );
  reader->SetFileNames( nameGenerator->GetFileNames()  );
  reader->Update();



  typedef int    PixelType1;
  const unsigned int      Dimension1 = 3;
  typedef itk::Image< PixelType1, Dimension1 >      ImageType1;
  typedef itk::ImageSeriesReader< ImageType1 >     ReaderType1;
  typedef itk::GDCMImageIO                        ImageIOType;
  typedef itk::GDCMSeriesFileNames                NamesGeneratorType;
  ImageIOType::Pointer gdcmIO = ImageIOType::New();
  NamesGeneratorType::Pointer namesGenerator1 = NamesGeneratorType::New();
  namesGenerator1->SetInputDirectory( argv[4] );
  const ReaderType1::FileNamesContainer & filenames1 = 
                            namesGenerator1->GetInputFileNames();
  unsigned int numberOfFilenames1 =  filenames1.size();
  std::cout << numberOfFilenames1 << std::endl; 
  for(unsigned int fni1 = 0; fni1<numberOfFilenames1; fni1++)
    {
    std::cout << "filename # " << fni1 << " = ";
    std::cout << filenames1[fni1] << std::endl;
    }

  ReaderType1::Pointer reader1 = ReaderType1::New();
  reader1->SetImageIO( gdcmIO );
  reader1->SetFileNames( filenames1 );
  try
    {
    // Software Guide : BeginCodeSnippet
    reader1->Update();
    // Software Guide : EndCodeSnippet
    }
  catch (itk::ExceptionObject &excp)
    {
    std::cerr << "Exception thrown while writing the image" << std::endl;
    std::cerr << excp << std::endl;
    return EXIT_FAILURE;
    }
  ImageType1::Pointer image=reader1->GetOutput();
  typedef itk::MetaDataDictionary   DictionaryType;
  const  DictionaryType & dictionary = gdcmIO->GetMetaDataDictionary();
  typedef itk::MetaDataObject< std::string > MetaDataStringType;
  std::string entryId = "0010|0010";
     DictionaryType::ConstIterator end = dictionary.End();
  DictionaryType::ConstIterator tagItr = dictionary.Find( entryId );
  if( tagItr == end )
    {
    std::cerr << "Tag " << entryId;
    std::cerr << " not found in the DICOM header" << std::endl;
    return EXIT_FAILURE;
    }
  MetaDataStringType::ConstPointer entryvalue = 
    dynamic_cast<const MetaDataStringType *>( tagItr->second.GetPointer() );
  std::string filename2 = argv[5];
  if( entryvalue )
    {
    std::string tagvalue = entryvalue->GetMetaDataObjectValue();
    std::cout << "Patient's Name (" << entryId <<  ") ";
    std::cout << " is: " << tagvalue << std::endl;
    std::ofstream  myfile;

  myfile.open(filename2.c_str(),std::ios::app);
  myfile<< "Patient's Name:  "<<tagvalue<<std::endl;
  myfile .close();
    }
  else
    {
    std::cerr << "Entry was not of string type" << std::endl;
    return EXIT_FAILURE;
    }
  //hacim ve alan hesabi
  ImageType::SizeType si;
    si=reader->GetOutput()->GetLargestPossibleRegion().GetSize();
     ImageType::IndexType pixelIndex;
      ImageType1::SpacingType sp;
   sp=image->GetSpacing();
  std::ofstream  myfile;
   myfile.open(filename2.c_str(),std::ios::app);
   myfile<< "n"<<std::endl;
    myfile<< "Areas: "<<std::endl;
    myfile<< "n"<<std::endl;
     double alann=sp[1]*sp[0];

  for(int k=si[2]-1;k>-1;k--)
   {
       int sayii=0;
     for(int i=0;i<si[0];i++)
        {
          for(int j=0;j<si[1];j++)
           {

                 pixelIndex[0] = i;  // x position
                 pixelIndex[1] =j ;  // y position
                 pixelIndex[2]= k;
                if(reader->GetOutput()->GetPixel(pixelIndex)==255)
                {
                sayii=sayii+1;
                }

           }
        }
    myfile<< "filename: "<<filenames1[k]<<"   "<<"Area : "<<alann*sayii<<"   mm_2"<<std::endl;

  }
    myfile .close();
  // end hacim

     volumerendering * vol = new volumerendering;


  std::string filename = argv[3];
  vtkSmartPointer<vtkXMLUnstructuredGridWriter> writer =
    vtkSmartPointer<vtkXMLUnstructuredGridWriter>::New();
  writer->SetFileName(filename.c_str());
  writer->SetInput( vol->volume(reader->GetOutput(),image,filename2));
  writer->Write();
  return EXIT_SUCCESS;
  }

volumerendering.cpp

    #ifndef _volumerendering_cpp
#define _volumerendering_cpp
#include"volumerendering.h"
#include <vtkSmartPointer.h>
#include <vtkDataSetMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>

#include <vtkPoints.h>
#include <vtkVoxel.h>
#include <vtkUnstructuredGrid.h>
#include <vtkParticleReader.h>
#include <vtkProperty.h>
#include <vtkPolyData.h>
#include <vtkCellArray.h>
#include <vtkDataSetSurfaceFilter.h>
#include <vtkPointSource.h>
 #include <vtkPointData.h>
#include <vtkSTLWriter.h>
#include <vtkVertexGlyphFilter.h>
#include<vtkPolyDataWriter.h>
vtkUnstructuredGrid* volumerendering::volume(itk::Image<unsigned short,3>::Pointer image,itk::Image<int,3>::Pointer image1,std::string outt )
{
    vtkUnstructuredGrid *ug = vtkUnstructuredGrid::New();
    vtkSmartPointer<vtkPoints> points =vtkSmartPointer<vtkPoints>::New();
    typedef itk::Image< unsigned short, 3 >      ImageType;
    typedef itk::Image< int, 3 >      ImageType1;
    ImageType::SizeType si;
    si=image->GetLargestPossibleRegion().GetSize();
     ImageType::IndexType pixelIndex;
      ImageType1::SpacingType sp;
   sp=image1->GetSpacing();

   // hacim vee alan hesapları
    double hacim=sp[1]*sp[0]*sp[2];
   //hacim ve alan hesabi son

     int fr=0;
    int hacimsayii=0;
    for(int i=0;i<si[0];i++)
    {
        for(int j=0;j<si[1];j++)
        {
            for(int k=0;k<si[2];k++)
            {
                 pixelIndex[0] = i;  // x position
                 pixelIndex[1] =j ;  // y position
                 pixelIndex[2]= k;
                if(image->GetPixel(pixelIndex)==255)
                {hacimsayii=hacimsayii+1;
                float a1[]={i*sp[0],j*sp[1],k*sp[2]};
                float a2[]={(i+1)*sp[0],j*sp[1],k*sp[2]};
                float a3[]={i*sp[0],(j+1)*sp[1],k*sp[2]};
                float a4[]={(i+1)*sp[0],(j+1)*sp[1],k*sp[2]};
                float a5[]={i*sp[0],j*sp[1],(k+1)*sp[2]};
                float a6[]={(i+1)*sp[0],j*sp[1],(k+1)*sp[2]};
                float a7[]={i*sp[0],(j+1)*sp[1],(k+1)*sp[2]};
                float a8[]={(i+1)*sp[0],(j+1)*sp[1],(k+1)*sp[2]};


                      points->InsertPoint(fr,a1);
                      points->InsertPoint(fr+1,a2);
                      points->InsertPoint(fr+2,a3);
                      points->InsertPoint(fr+3,a4);
                      points->InsertPoint(fr+4,a5);
                      points->InsertPoint(fr+5,a6);
                      points->InsertPoint(fr+6,a7);
                      points->InsertPoint(fr+7,a8);

                     fr=fr+8;
                }
            }
        }
    }
    std::ofstream  myfile;

  myfile.open(outt.c_str(),std::ios::app);
   myfile<< "n"<<std::endl;
    myfile<< "Volume "<<std::endl;
    myfile<< "n"<<std::endl;
  myfile<< "Total Volume=  "<<hacim*hacimsayii<<"  mm_3"<<std::endl;
  myfile .close();
    static int ptr[8];
    int tt=0;
    int cti=points->GetNumberOfPoints();
    for (int i=0;i<cti/8 ;i++)
   {
       for (int iy=0;iy<1;iy++)
       {
          ptr[0]=iy+tt;  ptr[1]=iy+tt+1;  ptr[2]=iy+tt+2;  ptr[3]=iy+tt+3;
           ptr[4]=iy+tt+4;  ptr[5]=iy+tt+5;  ptr[6]=iy+tt+6;  ptr[7]=iy+tt+7;
        ug->InsertNextCell(VTK_VOXEL,8,ptr);
        tt=tt+8;
       }
   }
  ug->SetPoints(points);

 /* vtkSmartPointer<vtkDataSetMapper> mapper = 
    vtkSmartPointer<vtkDataSetMapper>::New();
  mapper->SetInput(ug);
  vtkSmartPointer<vtkActor> actor = 
    vtkSmartPointer<vtkActor>::New();
  actor->SetMapper(mapper);
  vtkSmartPointer<vtkRenderWindow> renderWindow = 
    vtkSmartPointer<vtkRenderWindow>::New();
  vtkSmartPointer<vtkRenderer> renderer = 
    vtkSmartPointer<vtkRenderer>::New();
  renderWindow->AddRenderer(renderer);

  renderer->AddActor(actor);
  renderer->ResetCamera();
  vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = 
    vtkSmartPointer<vtkRenderWindowInteractor>::New();
  renderWindowInteractor->SetRenderWindow(renderWindow);
  renderWindow->Render();
  renderWindowInteractor->Start();*/
 return ug;
}
#endif

volumerendering.h

 #ifndef __volumerendering_h
#define __volumerendering_h
#include"vtkUnstructuredGrid.h"
#include"itkImage.h"
#include "itkImageSeriesReader.h"
class volumerendering
{
public:
    vtkUnstructuredGrid* volume(itk::Image<unsigned short,3>::Pointer image,itk::Image<int,3>::Pointer image1,std::string outt );
};
#endif

谢谢

volumerendering.cpp必须与项目一起编译。

但是我没有看到任何阻止volumerendering::volume被定义的东西,所以它可能是一个项目配置问题?

确保volumerendering.cppa.cpp同时编译