[Insight-users] passing itkImage to a function ...C++ template problem

Luis Ibanez luis.ibanez at kitware.com
Mon Oct 18 10:06:21 EDT 2004


Hi Lagaffe,

You are simply missing to include the .txx file in your .h header file.

As opposed to non-templated code, when you write templated classes,
the entire implementation of the methods must be available to those
units that instantieate your class.

   In other words:

      "main.cxx must know about Visualization.txx"



There are several ways of achieving this, some options are:


1) Put all the code in the .h header file

2) #include both the .h and .txx files in main.cxx

3) The style that was adopted in ITK is to include
    the .txx file into the .h header file. In this
    way you only need to include the .h file in main.cxx

    Note that for this to work correctly you need to
    put #ifdef guards in the .txx files in the same
    way that you do in the .h header file.

Loof for example at the end of the itkImage.h file
in Insight/Code/Common. You will find the lines:

         #ifndef ITK_MANUAL_INSTANTIATION
         #include "itkImage.txx"
         #endif

and if you look at the top of itkImage.txx, you will
find

          #ifndef _itkImage_txx
          #define _itkImage_txx




Regards,


    Luis



-------------------
Mr Gaffe wrote:
> Hello Luis,
> I am so sorry to ask you again but I tried again all the week end and It 
> still not compile ...
> Error happen during the link process:
>  
> MyApp error LNK2019: symbole externe non résolu "public: __thiscall 
> Visualization<class itk::Image<unsigned short,3> >::Visualization<class 
> itk::Image<unsigned short,3> >(void)" 
> (??0?$Visualization at V?$Image at G$02 at itk@@@@QAE at XZ 
> <mailto:??0?$Visualization at V?$Image at G$02 at itk@@@@QAE at XZ>) référencé dans 
> la fonction _main
> (for users not french:) *error* *LNK2019*: unresolved external *symbol* )
> here you will find my code, and I hope you can help me again, many thanks
> Lagaffe.
>  
> 1- // Visualization.h
> template <class VisualizationType> class Visualization
> {
> public:
>   
>  void volumeRendering(const VisualizationType *image);
>  Visualization(void);
>  ~Visualization(void);
> };
>  
> 2- // Visualization.txx
> #include "Visualization.h"
> template <class VisualizationType> 
> Visualization<VisualizationType>::Visualization(void) {
>  
>  renderer = vtkRenderer::New();
>  renWin = vtkRenderWindow::New();
>  renWin->AddRenderer(renderer);
>  iren = vtkRenderWindowInteractor::New();
>  iren->SetRenderWindow(renWin);
> }
> template <class VisualizationType> 
> Visualization<VisualizationType>::~Visualization(void)
> {
>  iren->Delete();
>  renWin->Delete();
>  renderer->Delete();
> }
> template <class VisualizationType> void 
> Visualization<VisualizationType>::volumeRendering(const 
> VisualizationType *image){
> ....
> 3- MyApp.cxx
>  
> #include "itkImage.h"
> #include "itkImageFileReader.h"
> #include "Visualization.h"
> //
> 
> int main(int argc, char **argv) {
> //
>  // Constitution de l'image
>  typedef itk::Image<unsigned short,3> ImageType;
>  typedef Visualization<ImageType> VisuType;
>  typedef itk::ImageFileReader<ImageType> ReaderType;
>  ReaderType::Pointer reader= ReaderType::New();
>  reader->SetFileName("t2w_1.hdr");
>  // Volume rendering
>  VisuType *visu= new VisuType();
>  visu->volumeRendering(reader->GetOutput());
>  return 0;
> }
>  
> ------------------------------------------------------------------------------------------------------------------
> 
> */Luis Ibanez <luis.ibanez at kitware.com>/* wrote:
> 
> 
>     Hi Lagaffe,
> 
>     The error is that your create a templated class where the
>     template paramter is supposed to be an ImageType, but you
>     are instantiating it using the *ReaderType*.
> 
> 
> 
>     Please replace
> 
>     BasicTransformation< ReaderType > *basic;
> 
> 
>     with
> 
>     BasicTransformation< ImageType > *basic;
> 
> 
> 
>     ALSO, from your code, it seems that you are
>     using "basic" without allocating it. I guess
>     that you probably intended to do:
> 
> 
>     typedef BasicTransformation MyClassType;
>     MyClassType * basic = new MyClassType;
> 
> 
> 
> 
> 
>     Regards,
> 
> 
>     Luis
> 
> 
>     -----------------------------------------
>     Mr Gaffe wrote:
> 
>      > Thanks luis for your help,
>      >
>      > I read the tutorial, but I still have a compilation problem... I
>     change
>      > my class to a template file as you sa! id (it is really more
>     simple), this
>      > is the code:
>      >
>      > // BasicTransformation.h
>      > template class BasicTransformation
>      > {
>      > public:
>      > template void doSomething(const *TImage image);
>      > BasicTransformation (void);
>      > ~BasicTransformation (void);
>      > };
>      > // BasicTransformation.txx
>      > #include "BasicTransformation.h"
>      > BasicTransformation::BasicTransformation(void) {
>      >
>      > }
>      > BasicTransformation::~BasicTransformation(void)
>      > {
>      >
>      > }
>      > template void
>      > BasicTransformation::doSomething(const *TImage image){
>      > ...
>      > start ITK Pipeline with : image->getOutput()
>      > ..
>      > }
>      > // My main function in MyApp.cpp
>      >
>      > int main(int argc, char **argv) {
>      >
>      > typedef itk::Image ImageType;
>      > typedef itk::ImageFileReader ReaderType;
>      > ReaderType::Pointer reader= ReaderType::New();
>      > reader->SetFileName("t2w_1.hdr");
>      >
>      > // Basic Transformation
>      > BasicTransformation *basic;
>      > basic->doSomething(reader->GetOutput);
>      >
>      > ==> Error during compilation: impossible to deduce TImage template
>      > argument with TImage=ReaderType
>      >
>      > If you have any idea, I will appreciate,
>      > Lagaffe
>      >
>      > */Luis Ibanez /* wrote:
>      >
>      >
>      >
>      > Hi Lagaffe,
>      >
>      >
>      > Your class BasicTransformation seems to be ok,
>      > however, you have to manage it as a templated class.
>      >
>      > That is, it must be in a .txx file and it will only
>      > get instantiated when you define the actual types.
>      >
>      >
>      > Your code will be much simpler is you just create
>      > BasicTransformation as a templated class, and use
>      > the ImageType a! s the template parameter.
>      >
>      > Something like
>      >
>      >
>      >
>      > template
>      > class BasicTransformation
>      > {
>      > public:
>      > void myFunction(const * TImage);
>      > };
>      >
>      >
>      >
>      >
>      > You are *strongly* encouraged to look at the Tutorial
>      > sessions:
>      >
>      > http://www.itk.org/HTML/Tutorials.htm
>      >
>      > in particular to
>      >
>      > http://www.itk.org/CourseWare/Training/GettingStarted-V.pdf
>      >
>      > where the integration of ITK classes inside non-ITK
>      > applications is discussed in detail.
>      >
>      >
>      > Plea! se let us know if you have further questions,
>      >
>      >
>      > Thanks
>      >
>      >
>      > Luis
>      >
>      >
>      >
>      > ----------------
>      > Mr Gaffe wrote:
>      >
>      > > Hello,
>      > > I a new to itk and I try to create my own class which can do some
>      > basic
>      > > itk transformation with templat! ed itk object, and I failed, I
>     really
>      > > don't know how to do this.
>      > >
>      > > In my .h declaration I did:
>      > >
>      > > class BasicTransformation
>      > >
>      > > {
>      > >
>      > > public:
>      > >
>      > > template void
>      > > myFunction(itk::Image imageData);
>      > >
>      > > }
>      > >
>      > > -> it doesn't compile, because I have to define all the template
>      > values
>      > > ? (so I don't understand how to use the template, since I had to
>      > specify
>      > > so early, my function have to work with different itkImage type
>     ...).
>      > >
>      > > If I specify the type it compile but it is not very interresting...
>      > >
>      > > template void
>      > > myFunction(itk::Image imageData);
>      > >
>      > > -> What is very weard is that if I use an ImageSource, it compiles
>      > > without specify the type of ImageSource .... (at this time!
>      > started to
>      > > begin mad :-)
>      > >
>      > > template void
>      > > volumeRendering(itk::ImageSource imageSource);
>      > >
>      > > So,
>      > >
>      > > -> 1 - can someone could explain to me how to pass a itk object
>     to a
>      > > function in another class, please .
>      > >
>      > > ->2 - In my processing class is it better to have an itkImage to
>      > begin
>      > > the process or an ImageSource ?
>      > >
>      > >
>      > > Thanks for help
>      > >
>      > > Lagaffe
>      > >
>      > >
>      > > _______________________________________________
>      > > Insight-users mailing list
>      > > Insight-users at itk.org
>      > > http://www.itk.org/mailman/listinfo/insight-users
>      >
>      >





More information about the Insight-users mailing list