[Insight-developers] Link errors and itk::NumericTraits on Windows
Zachary Pincus
zpincus at stanford.edu
Tue Apr 4 18:32:57 EDT 2006
Hi folks,
I've been tracking down a most annoying link problem with WrapITK on
Windows. After much banging of my head, I think that it may be an
actual issue with ITK itself.
Here is a brief description of what I think the problem is. On
Windows, constants exported from DLLs need to be marked with
ITKCommon_EXPORT. The NumericTraits<...>::Zero and ::One values are
examples of such constants.
For each template instantiation, ITKCommon_EXPORT is provided for
these values. However, in the template definition, there is no
ITKCommon_EXPORT preceding these symbols. (I'm sure there is a very
good reason for this.)
Here comes the tricky part: most classes that need NumericTraits will
only #include "itkNumericTraits.h". In itkNumericTraits.h, however,
traits for only the built in types are defined. Specializations for
things like RGBPixel are declared in separate NumericTraits headers.
When an class (in my case, itk::ConstantBoundaryCondition) is
instantiated with a pixel type like RGBPixel or CovariantVector, the
NumericTraits specialization is not included, because the class did
not #include "itkNumericTraitsRGBPixel.h", etc. Given that it is a
generic class, #including a special NumericTraits header is at least
easy for an author to forget, and at most counter to the principle of
generic types.
Now, because the class has seen the generic traits definition from
itkNumericTraits.h, the compiler can create a NumericTraits object
for something like RGBPixel, so there won't be a compile error. Now
we come full circle, however: this object's static members Zero and
One will *not* be marked with ITKCommon_EXPORT, because the generic
template definition does not mark Zero and One as ITKCommon_EXPORT.
So on Windows, the linker can't find them in the ITKCommon DLL.
Thus, building a such a class (like
itk::ConstantBoundaryCondition<itk::Image<itk::RGBPixel<unsigned
char>, 2> > ) will result in really strange link errors on Windows,
where the linker can't find the
itk::NumericTraits<itk::RGBPixel<unsigned char> >::Zero symbol in the
ITKCommon library, even though it is clearly defined in that library.
There are three possible solutions that I can think of:
(1) itkNumericTraits.h should #include all subsidiary NumericTraits
headers. Then generic filters can #include just one generic numeric
traits header, and be assured that regardless of what pixel types
they are instantiated with, the right NumericTraits objects will be
available.
(2) The NumericTraits class should declare that Zero and One are
ITKCommon_EXPORT. I don't know if this will break things.
(3) Every class that might potentially be instantiated over RGB or
vector pixels, etc, should #include all possible NumericTraits headers.
I think option 1 sounds the best. Are there any other approaches?
Does anyone have any ideas as to what to do here?
Zach
More information about the Insight-developers
mailing list