[Insight-developers] One possible framework for Image I/O...

Bill Hoffman bill.hoffman@kitware.com
Wed, 20 Dec 2000 12:05:50 -0500


--=====================_1019121609==_.ALT
Content-Type: text/plain; charset="us-ascii"


At 11:01 AM 12/20/00 -0500, Parag Chandra wrote:
>Hey Bill,
>  
>Sorry for the delay. If you modified the ObjectFactory to behave as you have described in your previous e-mail, that would be sufficient for the purposes of this I/O framework. The only reason I templated Maker over the key type is to keep it as flexible as possible. Although I cannot think of a specific example now, I had originally thought that it might be useful for others to use integers, or even entirely new classes, as the key type. But having a string key is probably all that will ever be needed.
>  
>Compiling the factories as DLLs sounds like a very good idea. I had previously tried to figure out the DynamicLoader class and compile an I/O factory as a DLL, but since I could not get Windows to load this library at runtime, I abandoned the idea. Is there some example for writing such a DLL? It seems that simply placing my source files into a new DLL project in VC++ is enough to get it to compile, but not enough for it to be loaded at runtime.
>  

The DynamicLoader works on windows and unix.   The key is that your 
DLL/shared library has to have an exported function that looks like
this:

extern "C" ObjectFactoryBase* itkLoad()
{
return new YourFactory;
}

In windows, you have to declspec(export) the function, but 
other than that, you can use the wizard in MSC++ to create a dll.


Also, it seems that I am faster than I thought....
I had already made those changes to the object factory in ITK.
See itkCreateObjectFunction.h

So, you should be able to re-work your stuff using the itk object
factories right now.

Just sub class from the BaseFactory, and in your constructor,

Call this function:

   void RegisterOverride(const char* classOverride,
                         const char* overrideClassName,
                         const char* description,
                         bool enableFlag,
                         CreateObjectFunctionBase* createFunction);

Something like this:

MyFactory::MyFactory()
{
RegisterOverride("ImageType", "ImageType", "Create ImageType", true,
                  CreateObjectFunction<ImageType>::New());
RegisterOverride("ImageType2", "ImageType2", "Create ImageType2", true,
                  CreateObjectFunction<ImageType2>::New());
}

This assumes that ImageType2 is an itkLightObject sub-class.

You can register your factory as a dll/shared library, or hard code it,
by calling:

itk::ObjectFactoryBase::RegisterFactory(new MyFactory);



To create objects you call:
itk::LightObject* obj = itk::ObjectFactoryBase::CreateInstance("ImageType");
then do the safe downcast, or you can use the templated objectfactory class
to use rtti and do the cast for you.


Let me know if you have any trouble.

-Bill

                 
>Thanks,
>-Parag
>  
>----- Original Message ----- 
>>From: <mailto:bill.hoffman@kitware.com>Bill Hoffman 
>>To: <mailto:Parag@Chandra.com>Parag Chandra ; <mailto:insight-developers@public.kitware.com>insight-Developers ; <mailto:will.schroeder@kitware.com>Will Schroeder 
>>Sent: Tuesday, December 19, 2000 10:29 AM
>>Subject: Re: [Insight-developers] One possible framework for Image I/O...
>>
>>Hi Parag,
>>
>>I have been looking at your Maker class.   The article on
>>pluggable factories was quite good.   I do think that with
>>slight modification the ObjectFactory could be used for
>>what you want.  This would avoid the confusion of having several
>>ways of doing something in the same system.   
>>
>>Although the ObjectFactory can use RTTI, it is not required.
>>At the end of the day, all you need is the virtual function 
>>
>>itkObject* CreateInstance(const char*);
>>
>>
>>I have recently added some features to the vtk object factory,
>>that I plan to add to the itk object factory.   Would it be sufficient
>>for your needs if ObjectFactory allowed you to register creation
>>objects based on a string, that CreateInstance would use?
>>Why does your key have to be templated?
>>
>>
>>
>>/**
>>  *   protected function used by sub classes of ObjectFactory to register
>>  *   creation objects with a given string name.   This would be put
>>  *   into a map, and used when CreateInstance is called with 
>>  *   classOverride as the string.
>>   */
>>void ObjectFactory::RegisterOverride(const char* classOverride,
>>                         const char* overrideClassName,
>>                         const char* description,
>>                         int enableFlag,  
>>                         CreateObject* createObject);
>>
>>The CreateObject, would be very similar to the itkCommand object, except
>>it would have a function that returned objects instead of just an
>>Execute function.
>>
>>
>>The advantage of working with the itk ObjectFactory framework , is that \
>>it supports dynamic loading and registration of factories.
>>You could create a dll with your MetaImage ObjectFactory sub class, with
>>all the registered CreateObjects for the keys you want to create, then
>>just put it in ITK_AUTOLOAD_PATH, and any pre-compiled itk executable 
>>would be able to load MetaImages.  It allows the system to be both
>>Open (you can add stuff at run time)  and Closed (the executable is compiled, and the interface is locked in).
>>
>>
>>
>>-Bill
>>
>>
>>
>>>2. I felt that itkMaker was necessary because there does not seem to be a
>>>way to use ObjectFactory to instantiate subclasses based on a user-supplied
>>>key value. ObjectFactory seems to use RTTI to automatically determine which
>>>class to instantiate and return.

--=====================_1019121609==_.ALT
Content-Type: text/html; charset="us-ascii"


At 11:01 AM 12/20/00 -0500, Parag Chandra wrote:
Hey Bill,
 
Sorry for the delay. If you modified the ObjectFactory to behave as you have described in your previous e-mail, that would be sufficient for the purposes of this I/O framework. The only reason I templated Maker over the key type is to keep it as flexible as possible. Although I cannot think of a specific example now, I had originally thought that it might be useful for others to use integers, or even entirely new classes, as the key type. But having a string key is probably all that will ever be needed.
 
Compiling the factories as DLLs sounds like a very good idea. I had previously tried to figure out the DynamicLoader class and compile an I/O factory as a DLL, but since I could not get Windows to load this library at runtime, I abandoned the idea. Is there some example for writing such a DLL? It seems that simply placing my source files into a new DLL project in VC++ is enough to get it to compile, but not enough for it to be loaded at runtime.
 

The DynamicLoader works on windows and unix.   The key is that your
DLL/shared library has to have an exported function that looks like
this:

extern "C" ObjectFactoryBase* itkLoad()
{
return new YourFactory;
}

In windows, you have to declspec(export) the function, but
other than that, you can use the wizard in MSC++ to create a dll.


Also, it seems that I am faster than I thought....
I had already made those changes to the object factory in ITK.
See itkCreateObjectFunction.h

So, you should be able to re-work your stuff using the itk object
factories right now.

Just sub class from the BaseFactory, and in your constructor,

Call this function:

  void RegisterOverride(const char* classOverride,
                        const char* overrideClassName,
                        const char* description,
                        bool enableFlag,
                        CreateObjectFunctionBase* createFunction);

Something like this:

MyFactory::MyFactory()
{
RegisterOverride("ImageType", "ImageType", "Create ImageType", true,
                 CreateObjectFunction<ImageType>::New());
RegisterOverride("ImageType2", "ImageType2", "Create ImageType2", true,
                 CreateObjectFunction<ImageType2>::New());
}

This assumes that ImageType2 is an itkLightObject sub-class.

You can register your factory as a dll/shared library, or hard code it,
by calling:

itk::ObjectFactoryBase::RegisterFactory(new MyFactory);



To create objects you call:
itk::LightObject* obj = itk::ObjectFactoryBase::CreateInstance("ImageType");
then do the safe downcast, or you can use the templated objectfactory class
to use rtti and do the cast for you.


Let me know if you have any trouble.

-Bill

                
Thanks,
-Parag
 
----- Original Message -----
From: Bill Hoffman
To: Parag Chandra ; insight-Developers ; Will Schroeder
Sent: Tuesday, December 19, 2000 10:29 AM
Subject: Re: [Insight-developers] One possible framework for Image I/O...

Hi Parag,

I have been looking at your Maker class.   The article on
pluggable factories was quite good.   I do think that with
slight modification the ObjectFactory could be used for
what you want.  This would avoid the confusion of having several
ways of doing something in the same system.  

Although the ObjectFactory can use RTTI, it is not required.
At the end of the day, all you need is the virtual function

itkObject* CreateInstance(const char*);


I have recently added some features to the vtk object factory,
that I plan to add to the itk object factory.   Would it be sufficient
for your needs if ObjectFactory allowed you to register creation
objects based on a string, that CreateInstance would use?
Why does your key have to be templated?



/**
 *   protected function used by sub classes of ObjectFactory to register
 *   creation objects with a given string name.   This would be put
 *   into a map, and used when CreateInstance is called with
 *   classOverride as the string.
  */
void ObjectFactory::RegisterOverride(const char* classOverride,
                        const char* overrideClassName,
                        const char* description,
                        int enableFlag, 
                        CreateObject* createObject);

The CreateObject, would be very similar to the itkCommand object, except
it would have a function that returned objects instead of just an
Execute function.


The advantage of working with the itk ObjectFactory framework , is that \
it supports dynamic loading and registration of factories.
You could create a dll with your MetaImage ObjectFactory sub class, with
all the registered CreateObjects for the keys you want to create, then
just put it in ITK_AUTOLOAD_PATH, and any pre-compiled itk executable
would be able to load MetaImages.  It allows the system to be both
Open (you can add stuff at run time)  and Closed (the executable is compiled, and the interface is locked in).



-Bill



2. I felt that itkMaker was necessary because there does not seem to be a
way to use ObjectFactory to instantiate subclasses based on a user-supplied
key value. ObjectFactory seems to use RTTI to automatically determine which
class to instantiate and return.
--=====================_1019121609==_.ALT--