[Insight-users] Undefined reference to a templated function. Error in compilation.
Seth Gilchrist
seth at mech.ubc.ca
Thu Mar 10 19:14:22 EST 2011
Hi all,
I am getting the following error when compiling my program:
CMakeFiles/TestProgram.dir/TestProgram.cxx.o: In function `main':
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()'
collect2: ld returned 1 exit status
make[2]: *** [TestProgram] Error 1
make[1]: *** [CMakeFiles/TestProgram.dir/all] Error 2
make: *** [all] Error 2
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:
http://bytes.com/topic/c/answers/128614-undefined-reference-template-class)
but none of this is reflected in any textbooks that I have referenced.
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.
Thanks,
Seth
ubuntu 10.10 64bit
ITK 3.20 (Paul Novo's build 3.20.0-novo 1)
VTK 5.4 (5.4.2-7ubuntu3)
gcc 4:4.4.4-1ubuntu2
g++ 4:4.4.4-1ubuntu2
cmake 2.8.3-1~maverick1
################## TestProgram.cxx #########
#include <iostream>
#include "DIC.hxx"
#include "DICMesh.hxx"
int main(int argc, char **argv)
{
// create the images
typedef short ImagePixelType;
const unsigned int dimension = 3;
typedef itk::Image< ImagePixelType, dimension > FixedImageType;
typedef itk::Image< ImagePixelType, dimension >
MovingImageType;
typedef double MeshPixelComponentType;
typedef itk::Vector< MeshPixelComponentType,4 > MeshPixelType;
typedef itk::Mesh< MeshPixelType, dimension > MeshType;
MeshType::Pointer mesh = MeshType::New(); // the mesh to be filled
with the points
// create the image readers
typedef itk::ImageFileReader< FixedImageType >
FixedImageReaderType;
typedef itk::ImageFileReader< MovingImageType >
MovingImageReaderType;
FixedImageReaderType::Pointer fixedReader =
FixedImageReaderType::New();
MovingImageReaderType::Pointer movingReader =
MovingImageReaderType::New();
fixedReader->SetFileName( argv[1] );
movingReader->SetFileName( argv[2] );
try
{
fixedReader->Update();
movingReader->Update();
}
catch( itk::ExceptionObject & err )
{
std::cerr<<"Error updating fixed and moving readers"<<std::endl;
std::cerr<<"Message:"<<std::endl;
std::cerr<<err<<std::endl<<std::endl;
return EXIT_FAILURE;
}
// test creating a DICMesh filter
DICMesh<FixedImageType,MovingImageType,MeshType> DICMethod;
std::cout<<"DICMethod created."<<std::endl;
return 0;
}
######### DIC.hxx ############
#ifndef DIC_H
#define DIC_H
#include <iostream>
#include <vector>
#include "itkImage.h"
#include "itkVector.h"
#include "itkRegionOfInterestImageFilter.h"
#include "itkImageRegistrationMethod.h"
#include "itkMeanSquaresImageToImageMetric.h" // default metric
#include "itkRegularStepGradientDescentOptimizer.h" // default optimizer
#include "itkTranslationTransform.h" // default transform
#include "itkLinearInterpolateImageFunction.h" // default interpolator
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
template <typename TFixedImage, typename TMovingImage>
class DIC
{
public:
/** Types and member functions**/
protected:
DIC();
~DIC() {}
private:
/** unititalized private variables. **/
}; // end class DIC
#endif // DIC_H
########### DIC.cxx ############
#include "DIC.hxx"
template <typename TFixedImage, typename TMovingImage>
DIC<TFixedImage,TMovingImage>
::DIC()
{
m_FixedImage = 0; // must be provided by user
m_MovingImage = 0; // must be provided by user
m_IRRadius = 0; // must be provided by user
/** Setup the default registration method.*/
m_Registration = ImageRegistrationMethodType::New();
m_Metric = itk::MeanSquaresImageToImageMetric< TFixedImage,
TMovingImage>::New();
m_Optimizer = itk::RegularStepGradientDescentOptimizer::New();
m_Transform = itk::TranslationTransform< double,
FixedImageType::ImageDimension >::New();
m_Interpolator = itk::LinearInterpolateImageFunction< TFixedImage,
double >::New();
m_Registration->SetMetric(m_Metric);
m_Registration->SetOptimizer(m_Optimizer);
m_Registration->SetTransform(m_Transform);
m_Registration->SetInterpolator(m_Interpolator);
m_CurrentFixedImage = 0;
m_CurrentMovingImage = 0;
UseWholeMovingImage = false;
m_MovingIRMult = 3; // default size of the moving IR is 3 times the size
of the fixed IR
m_CurrentFixedImage = 0;
m_FixedImageRegionList = 0;
m_MovingImageRegionList = 0;
}
/** All those other members. **/
############## DICMesh.hxx #############
#ifndef DICMESH_H
#define DICMESH_H
#include <iostream>
#include <fstream>
#include <cstring>
#include "DIC.hxx"
#include "itkMesh.h"
template<typename TFixedImage, typename TMovingImage, typename TMeshType>
class DICMesh : public DIC<TFixedImage, TMovingImage>
{
public:
/** Typedefs for DICMesh*/
/** Inherited typedefs from DIC.*/
/*...A bunch of member functions that are never called in
TestProgram.cxx...*/
DICMesh();
~DICMesh() {}
private:
/** unititalized private variables. **/
}; // end class DICMesh
#endif // DICMESH_H
############### DICMesh.cxx ############
#include "DICMesh.hxx"
template<typename TFixedImage, typename TMovingImage, typename TMeshType>
DICMesh<TFixedImage, TMovingImage, TMeshType>
::DICMesh()
{
m_OutputImage = 0; // must be provided by user
m_InitialDataImage = 0; // must be provided by user
}
/** Other members **/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.itk.org/pipermail/insight-users/attachments/20110310/cc3ae70a/attachment.htm>
More information about the Insight-users
mailing list