[Insight-users] Re: [Insight-users]Linking error
Luis Ibanez
luis . ibanez at kitware . com
Mon, 22 Dec 2003 16:25:40 -0500
Hi Radhika,
When you use templates, the definition of function bodies
must be visible from the header file, you cannot put this
code in a .cxx file.
You have two options
1) leave the full function body in the header file.
or
2) put the function body in a file with extension ".txx"
and include this file from the header .h file. Typically
you can do at the end of the .h file:
#include "myfunction.txx"
If you look at any ITK header file you will see this
at the end of the file.
Please reconsider the use of this code in the form of a
Functor or Calculator class. If the body of the function
is longer than 10 lines of code, you will end up sooner or
later having to debug and maintain this code. Having defined
this as a Functor will make much simpler to manage the code.
Regards,
Luis
----------------------------------
Radhika Sivaramakrishna wrote:
>Hi Luis,
>Thanks for the detailed response and attached file for function definition.
>As you suggested
>I used method 3. It was very useful and I was able to successfully get the
>function working.
>I now have another question.
>I decided to put the function body in a different file, created a .h file
>with the function definition and other include files that I included in the
>main file and the function file. I changed my CMakeLists file
>to include both .cxx files in the Add_Executable statement.
>Then I ran CMakeSetup and loaded the .dsw into Visual C++. The compiling
>process is fine but
>at the linking stage, it is not able to recognize the function. In the
>include statement, I even included the entire path of the include file
>thinking that that might be the problem. But that also did not work.
>What could be the problem?
>Thanks
>Radhika
>
>
>
>----- Original Message -----
>From: "Luis Ibanez" <luis . ibanez at kitware . com>
>To: "Radhika Sivaramakrishna" <radshashi at earthlink . net>
>Cc: <insight-users at itk . org>
>Sent: Monday, December 22, 2003 11:02 AM
>Subject: Re: [Insight-users] Function definition error
>
>
>
>
>>Hi Radhika,
>>
>>ITK filters on GetOutput() return *raw* pointers to images
>>not SmartPointers. The reason for doing this is that the filter
>>internally holds a smart pointer to its input.
>>
>>You can receive a raw pointer into a SmartPointer of the
>>appropriate type. However the conversion is not enough
>>for the compiler to figure out that your templated function
>>matches the type.
>>
>>You have the following options:
>>
>>1) The arguments to the BSI() function should be
>>
>> itk::Image< PixelType, 3> *
>>
>> instead of
>>
>> itk::Image< PixelType, 3> ::Pointer
>>
>>2) Even better, you could template the function over the
>> image type as:
>>
>>template <class TImageType>
>>float BSI2( TImageType * image1, TImageType * image2,
>> TImageType * mask1, TImageType * mask2,
>> float i1,float i2,float K)
>>
>>
>>3) And you will have a longer and more pleasant life if you
>> also embrace const-correctness, like in
>>
>> template <class TImageType>
>> float BSI3( const TImageType * image1, const TImageType * image2,
>> const TImageType * mask1, const TImageType * mask2,
>> float i1,float i2,float K)
>>
>> Since nobody is allowed to change the output of an ITK filter.
>>
>>
>>Please find attached a file with these three options.
>>
>>I would encourage you to use the model of BSI3.
>>
>>
>>
>>The best way to go though is to use classes instead of functions.
>>In this case, you can create a "Calculator" class which is a templated
>>class with an "Execute()" method. You connect all the images as inputs
>>and then invoke the Execute() methods with no arguments.
>>
>>
>>Regards,
>>
>>
>> Luis
>>
>>
>>---------------------------------------
>>Radhika Sivaramakrishna wrote:
>>
>>
>>
>>>Hi Luis,
>>>I was trying to define a function templated over the pixel type to
>>>which four images along with some other numbers of type float are
>>>passed and it returns a float.
>>>I am getting an error that I cannot understand. I am sure it is very
>>>straightforward. Could you tell me whats the problem? I have enclosed
>>>below the error I am getting, the way I am calling the function from
>>>main and also how the function has been defined.
>>>
>>>Radhika
>>>
>>>error C2784: 'float __cdecl BSI(class itk::SmartPointer<class
>>>itk::Image<PixelType,`template-parameter258'> >,class
>>>itk::SmartPointer<class itk::Image<PixelType,`template-parameter258'>
>>>
>>>
>>>>,class itk::SmartPoint
>>>>
>>>>
>>>er<class itk::Image<PixelType,`template-parameter258'> >,class
>>>itk::SmartPointer<class itk::Image<PixelType,`template-parameter258'>
>>>
>>>
>>>>,float,float,float)' : could not deduce template argument for 'class
>>>>
>>>>
>>>itk::SmartPointer<class itk::Image<TObjectType
>>>,`template-parameter258'> >' from 'class itk::Image<unsigned char,3> *'
>>>
>>>int main()
>>>{
>>>...
>>>
>>>float bsivalue =
>>>
>>>
>>>
>BSI(readerimage1->GetOutput(),readerimage2->GetOutput(),readermask1->GetOutp
>ut(),readermask2->GetOutput(),i1,i2,K);
>
>
>>>...
>>>}
>>>
>>>template <class PixelType> float BSI(itk::Image< PixelType,
>>>3>::Pointer image1,itk::Image< PixelType, 3>::Pointer
>>>image2,itk::Image< PixelType, 3>::Pointer mask1,itk::Image< PixelType,
>>>3>::Pointer mask2,float i1,float i2,float K)
>>>{
>>>// Body of function
>>>}
>>>
>>>
>>>
>>>
>>>
>>---------------------------------------------------------------------
>>
>>
>>
>>
>>
>
>
>----------------------------------------------------------------------------
>----
>
>
>
>
>>#include "itkImage.h"
>>#include "itkImageFileReader.h"
>>
>>
>>typedef itk::Image< unsigned char, 3 > ImageType;
>>
>>template <class PixelType>
>>float BSI(typename itk::Image< PixelType, 3>::Pointer image1,
>> typename itk::Image< PixelType, 3>::Pointer image2,
>> typename itk::Image< PixelType, 3>::Pointer mask1,
>> typename itk::Image< PixelType, 3>::Pointer mask2,
>> float i1,float i2,float K)
>>{
>> return 2.0;
>>}
>>
>>
>>template <class PixelType>
>>float BSI(itk::Image< PixelType, 3> * image1,
>> itk::Image< PixelType, 3> * image2,
>> itk::Image< PixelType, 3> * mask1,
>> itk::Image< PixelType, 3> * mask2,
>> float i1,float i2,float K)
>>{
>> return 2.0;
>>}
>>
>>template <class TImageType>
>>float BSI2( TImageType * image1,
>> TImageType * image2,
>> TImageType * mask1,
>> TImageType * mask2,
>> float i1,float i2,float K)
>>{
>> return 2.0;
>>}
>>
>>template <class TImageType>
>>float BSI3( const TImageType * image1,
>> const TImageType * image2,
>> const TImageType * mask1,
>> const TImageType * mask2,
>> float i1,float i2,float K)
>>{
>> return 2.0;
>>}
>>
>>
>>int main()
>>{
>>
>>typedef itk::ImageFileReader< ImageType > FilterType;
>>
>>FilterType::Pointer readerimage1 = FilterType::New();
>>FilterType::Pointer readerimage2 = FilterType::New();
>>FilterType::Pointer readermask1 = FilterType::New();
>>FilterType::Pointer readermask2 = FilterType::New();
>>
>>float i1 = 1.0;
>>float i2 = 1.0;
>>float K = 1.0;
>>
>>float bsivalue =
>> BSI( readerimage1->GetOutput(),
>> readerimage2->GetOutput(),
>> readermask1->GetOutput(),
>> readermask2->GetOutput(),
>> i1,i2,K);
>>
>>float bsivalue2 =
>> BSI2( readerimage1->GetOutput(),
>> readerimage2->GetOutput(),
>> readermask1->GetOutput(),
>> readermask2->GetOutput(),
>> i1,i2,K);
>>
>>float bsivalue3 =
>> BSI3( readerimage1->GetOutput(),
>> readerimage2->GetOutput(),
>> readermask1->GetOutput(),
>> readermask2->GetOutput(),
>> i1,i2,K);
>>
>>
>>}
>>
>>
>>
>>
>>
>>
>>
>>
>
>
>_______________________________________________
>Insight-users mailing list
>Insight-users at itk . org
>http://www . itk . org/mailman/listinfo/insight-users
>
>
>