[Insight-users] How to extend ITK with DLLs at runtime?

Gavin Baker gavinb+xtk at cs . mu . OZ . AU
Thu, 15 May 2003 11:57:50 +1000


Hello Parag,

On Wed, May 14, 2003 at 04:02:35PM -0400, Parag Chandra wrote:

> I am trying to use the DynamicLoader and ObjectFactory mechanism to create
> subclasses which can be packaged into shared libraries and then loaded
> dynamically at runtime. I know that the ImageIO framework was designed to
> allow this sort of behavior, but I don't understand all the details of how
> to make it work. Looking at ImageIOFactory, it's clear that
> ObjectFactoryBase::CreateAllInstance is called in order to create all the
> registered subclasses of a particular base class. 

> Each of these subclasses is then queried to determine which, if any, is
> the correct one to handle a particular image format.

The .CanReadFile(...) is called on each ImageIO class (in order of
registration) and the first one to return success gets to load it.

> However, all of these subclasses are essentially linked in statically at
> compile time, and their corresponding factories are explicitly registered
> via ImageIOFactory::RegisterBuiltInFactories.

These are just the default handlers; you can add your own at any time.

> If I wrote a new ImageIO class and packaged it as a shared library, how
> would I get it to automatically register its presence with the master
> ObjectFactoryBase at runtime?

To make an ImageIO 'plugin' for the Frobozz format, you need a few essential
elements:

1. A FrobozzImageIOFactory derived from ObjectFactoryBase, that registers
   your actual image handler class FrobozzImageIO

2. A FrobozzImageIO derived from ImageIOBase, that implements the normal 
   methods:

        CanReadFile(), Read(), CanWriteFile(), Write()

3. A library initialisation function:

        itk::ObjectFactoryBase* itkLoad()
        {
            return itk::FrobozzImageIOFactory::New();
        }

   that returns a new instance of your factory.

Basically you build the shared library as normal, and drop it into a path
somewhere that is pointed to by ITK_AUTOLOAD_PATH (described below).

> There is a mention of ITK_AUTOLOAD_PATH in the documentation; do I just
> put the DLL containing the object and its object factory into this path?

Yes - you just put the shared object (or DLL as appropriate) somewhere on
this path.  This .so should include (at a minimum) the two classes mentioned
above.  If you are using an external/3rd party shared library to do the
actual file I/O, obviously this would need to be on the regular path.

> What is this path and how would I modify it? I would really appreciate
> some step-by-step instructions or sample code for accomplishing
> this. Thanks in advance.

It is just an environment variable.  If it is set, the ObjectFactoryBase
will iterate through each path in the list (separated by ; or : depending on
platform).  It will try to load any shared libraries it finds (eg. on Unix,
"lib*.so") and if there is a function called "itkLoad" it will call it,
expecting to get an ObjectFactory in return.  It will then register this new
object factory, which will install your IO handler (as described above).

An example of setting it (under *nix):

    % export ITK_AUTOLOAD_PATH=/home/joe/itk/Frobozz/lib

I note that you have already found the bug in the Analyze code [1] - I also
reported this a little while ago [2].  I just had a look through CVS and it
looks like this was actually fixed in Revision 1.14.2.1 of
itkAnalyzeImageIO.cxx [3] so if you use the CVS release it should work fine.

[1] http://www.itk.org/pipermail/insight-users/2003-May/003564.html
[2] http://www.itk.org/pipermail/insight-users/2003-April/003377.html
[3] http://www.itk.org/cgi-bin/viewcvs.cgi/Code/IO/itkAnalyzeImageIO.cxx.diff?r1=1.14&r2=1.14.2.1&cvsroot=Insight

I have written an ImageIO loader extension for TIFF files using libtiff [4],
which was based on one of the existing ImageIO classes in
InsightToolkit/Code/IO.  I will be posting this soon, but I can send you an
'alpha' if you like.

[4] http://www.libtiff.org/

I hope this is of some use; let me know how you go... Regards,

  :: Gavin

-- 
Gavin Baker                                Computer Vision Lab (CVMIL)
http://www.cs.mu.oz.au/~gavinb                 University of Melbourne