Hi all,<br>I am getting the following error when compiling my program:<br><br> CMakeFiles/TestProgram.dir/TestProgram.cxx.o: In function `main':<br> TestProgram.cxx:(.text+0x18a): undefined reference to `DICMesh<itk::Image<short, 3u>, itk::Image<short, 3u>, itk::Mesh<itk::Vector<double, 4u>, 3u, itk::DefaultStaticMeshTraits<itk::Vector<double, 4u>, 3u, 3u, float, float, itk::Vector<double, 4u> > > >::DICMesh()'<br>
collect2: ld returned 1 exit status<br> make[2]: *** [TestProgram] Error 1<br> make[1]: *** [CMakeFiles/TestProgram.dir/all] Error 2<br> make: *** [all] Error 2<br><br>The problem is with instantiation of a templated class. The class is called DICMesh and inherits a bunch of stuff from a class called DIC. TestProgram.cxx and the (truncated) DIC and DICMesh hxx/cxx files containing the constructors are below. There seems to be something about having to use "export" (which I'm not very familiar with) or maybe #include'ing the cxx file in the hxx file (from here: <a href="http://bytes.com/topic/c/answers/128614-undefined-reference-template-class">http://bytes.com/topic/c/answers/128614-undefined-reference-template-class</a>) but none of this is reflected in any textbooks that I have referenced.<br>
<br>Does anybody have a recommendation or a reference that I could look at to solve this? I am newish to C++ (only ever programed main functions to this point) so you may see lots of yet unidentified errors as I can't even start the de-bugging until I get this solved.<br>
<br>Thanks,<br>Seth<br>ubuntu 10.10 64bit<br>ITK 3.20 (Paul Novo's build 3.20.0-novo 1)<br>VTK 5.4 (5.4.2-7ubuntu3)<br>gcc 4:4.4.4-1ubuntu2<br>g++ 4:4.4.4-1ubuntu2<br>cmake 2.8.3-1~maverick1<br><br><br>################## TestProgram.cxx #########<br>
<br>#include <iostream><br>#include "DIC.hxx"<br>#include "DICMesh.hxx"<br><br>int main(int argc, char **argv)<br>{<br> // create the images<br> typedef short ImagePixelType;<br>
const unsigned int dimension = 3;<br> typedef itk::Image< ImagePixelType, dimension > FixedImageType;<br> typedef itk::Image< ImagePixelType, dimension > MovingImageType;<br> <br>
typedef double MeshPixelComponentType;<br> typedef itk::Vector< MeshPixelComponentType,4 > MeshPixelType;<br> typedef itk::Mesh< MeshPixelType, dimension > MeshType;<br>
MeshType::Pointer mesh = MeshType::New(); // the mesh to be filled with the points<br> <br> // create the image readers<br> typedef itk::ImageFileReader< FixedImageType > FixedImageReaderType;<br>
typedef itk::ImageFileReader< MovingImageType > MovingImageReaderType;<br> <br> FixedImageReaderType::Pointer fixedReader = FixedImageReaderType::New();<br> MovingImageReaderType::Pointer movingReader = MovingImageReaderType::New();<br>
<br> fixedReader->SetFileName( argv[1] );<br> movingReader->SetFileName( argv[2] );<br> <br> try<br> {<br> fixedReader->Update();<br> movingReader->Update();<br> }<br> catch( itk::ExceptionObject & err )<br>
{<br> std::cerr<<"Error updating fixed and moving readers"<<std::endl;<br> std::cerr<<"Message:"<<std::endl;<br> std::cerr<<err<<std::endl<<std::endl;<br>
return EXIT_FAILURE;<br> }<br> <br> // test creating a DICMesh filter<br> DICMesh<FixedImageType,MovingImageType,MeshType> DICMethod;<br> <br> std::cout<<"DICMethod created."<<std::endl;<br>
<br> <br> return 0;<br>}<br><br>######### DIC.hxx ############<br><br>#ifndef DIC_H<br>#define DIC_H<br><br>#include <iostream><br>#include <vector><br>#include "itkImage.h"<br>#include "itkVector.h"<br>
#include "itkRegionOfInterestImageFilter.h"<br>#include "itkImageRegistrationMethod.h"<br>#include "itkMeanSquaresImageToImageMetric.h" // default metric<br>#include "itkRegularStepGradientDescentOptimizer.h" // default optimizer<br>
#include "itkTranslationTransform.h" // default transform<br>#include "itkLinearInterpolateImageFunction.h" // default interpolator<br>#include "itkImageFileReader.h"<br>#include "itkImageFileWriter.h"<br>
<br>template <typename TFixedImage, typename TMovingImage><br>class DIC<br>{<br>public:<br> /** Types and member functions**/<br> <br>protected:<br> DIC();<br> ~DIC() {}<br> <br>private:<br> /** unititalized private variables. **/<br>
<br>}; // end class DIC<br><br>#endif // DIC_H<br><br>########### DIC.cxx ############<br><br>#include "DIC.hxx"<br><br>template <typename TFixedImage, typename TMovingImage><br>DIC<TFixedImage,TMovingImage><br>
::DIC()<br>{<br> m_FixedImage = 0; // must be provided by user<br> m_MovingImage = 0; // must be provided by user<br> m_IRRadius = 0; // must be provided by user<br> <br> /** Setup the default registration method.*/<br>
m_Registration = ImageRegistrationMethodType::New();<br> m_Metric = itk::MeanSquaresImageToImageMetric< TFixedImage, TMovingImage>::New();<br> m_Optimizer = itk::RegularStepGradientDescentOptimizer::New();<br>
m_Transform = itk::TranslationTransform< double, FixedImageType::ImageDimension >::New();<br> m_Interpolator = itk::LinearInterpolateImageFunction< TFixedImage, double >::New();<br> m_Registration->SetMetric(m_Metric);<br>
m_Registration->SetOptimizer(m_Optimizer);<br> m_Registration->SetTransform(m_Transform);<br> m_Registration->SetInterpolator(m_Interpolator);<br> <br> m_CurrentFixedImage = 0;<br> m_CurrentMovingImage = 0;<br>
<br> UseWholeMovingImage = false;<br> m_MovingIRMult = 3; // default size of the moving IR is 3 times the size of the fixed IR<br> m_CurrentFixedImage = 0;<br> m_FixedImageRegionList = 0;<br> m_MovingImageRegionList = 0;<br>
}<br><br>/** All those other members. **/<br><br>############## DICMesh.hxx #############<br><br>#ifndef DICMESH_H<br>#define DICMESH_H<br><br>#include <iostream><br>#include <fstream><br>#include <cstring><br>
#include "DIC.hxx"<br>#include "itkMesh.h"<br><br>template<typename TFixedImage, typename TMovingImage, typename TMeshType><br>class DICMesh : public DIC<TFixedImage, TMovingImage><br>{<br>
public:<br><br> /** Typedefs for DICMesh*/<br> <br> /** Inherited typedefs from DIC.*/<br> <br> /*...A bunch of member functions that are never called in TestProgram.cxx...*/<br><br> DICMesh();<br>
~DICMesh() {}<br><br>private:<br> /** unititalized private variables. **/ <br> <br>}; // end class DICMesh<br><br>#endif // DICMESH_H<br><br>############### DICMesh.cxx ############<br><br>#include "DICMesh.hxx"<br>
<br>template<typename TFixedImage, typename TMovingImage, typename TMeshType><br>DICMesh<TFixedImage, TMovingImage, TMeshType><br>::DICMesh()<br>{<br> m_OutputImage = 0; // must be provided by user<br> m_InitialDataImage = 0; // must be provided by user <br>
}<br><br>/** Other members **/<br>