[Insight-developers] [Insight-users] INSIGHT JOURNAL: managedITK (ITK 3.8 ?) & Release Schedule

Dan Mueller dan.muel at gmail.com
Thu Jul 10 11:17:08 EDT 2008


Hi Bill,

Basically ManagedITK works by creating a C++/CLI class for each filter
instance, passing method calls/property changes/events to/from the
managed/native world. When I say "managed" I mean CIL (Common
Intermediate Language) code (like Java byte code) which is run on the
CLR (common language runtime) (a virtual machine). C++/CLI is a set of
C++ "extensions" proposed by Microsoft. Using C++/CLI in this way is
called "It Just Works" or by the new name "Interop Technologies":
    http://msdn2.microsoft.com/en-us/magazine/cc163971.aspx

There are a set of template C++/CLI files (in
ManagedITK/Source/Common) with empty configuration strings waiting to
be filled. To answer your question: yes, you need a managed
method/property for every native method/property. Most of these are
common and therefore stored as templates in the "Common" folder. Those
that are filter specific (such as the Variance property in your email)
are emitted by the managed_*.cmake file. Once all the configuration
strings have been filled, the final generated C++/CLI code is compiled
by the Visual Studio compiler with some special flags (/clr, etc.).
Then "it just works": you can call native code from managed code.

You can take at look at the generated file after configuring
ManagedITK (these are located in Build/Source/Modules). I have
attached one below for your reference.

HTH

Dan

/*=============================================================================

  NOTE: THIS FILE WAS AUTOMATICALLY GENERATED BY THE ManagedITK PROJECT.

  Project:   ManagedITK
  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkManagedMinimumMaximumImageCalculator_IF2.cxx
  Language:  C++/CLI
  Author:    Dan Mueller
  Date:      $Date: 2008-06-21 09:20:09 +0200 (Sat, 21 Jun 2008) $
  Revision:  $Revision: 18 $

  Portions of this code are covered under the ITK and VTK copyright.
  See http://www.itk.org/HTML/Copyright.htm for details.
  See http://www.kitware.com/VTKCopyright.htm for details.

  Copyright (c) 2008 Queensland University of Technology (QUT)

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files (the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions:

  The above copyright notice and this permission notice shall be included in
  all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  THE SOFTWARE.

=============================================================================*/

#pragma once
#pragma warning( disable : 4635 ) // Disable warnings about XML doc comments

#ifndef __itkManagedMinimumMaximumImageCalculator_IF2_cxx
#define __itkManagedMinimumMaximumImageCalculator_IF2_cxx

// Include some useful ITK headers
#pragma unmanaged
#include "itkDataObject.h"
#include "itkImage.h"
#include "itkExceptionObject.h"
#include "itkProcessObject.h"
#include "itkImageSource.h"
#include "itkImageToImageFilter.h"
#include "itkMinimumMaximumImageCalculator.h"


// Include some useful ManagedITK files
#pragma managed
#include "itkManagedTypes.cxx"
#include "itkManagedObjectAutoPtr.cxx"
#include "itkManagedObjectCommand.cxx"
#include "itkManagedProcessObjectCommand.cxx"
#include "itkManagedMinimumMaximumImageCalculator.cxx"

// Use some managed namespaces
#using <mscorlib.dll>
#using <System.dll>
#using <ManagedITK.Common.dll>
using namespace System;
using namespace System::IO;
using namespace System::Reflection;
using namespace System::ComponentModel;
using namespace System::Diagnostics;

// Some other necessary includes
namespace itk
{

///<summary>
///This class is a managed type instance for
itk::MinimumMaximumImageCalculator .
///</summary>
public ref class itkMinimumMaximumImageCalculator_IF2 :
    itkObject, IMinimumMaximumImageCalculator
{
private:
    // NativeType
    typedef itk::MinimumMaximumImageCalculator < itk::Image< float,2 >
> NativeType;
    typedef NativeType::ImageType ImageType;
    itkObjectAutoPtr<NativeType> m_PointerToNative;

protected:
    ///<summary>Protected constructor.</summary>
    itkMinimumMaximumImageCalculator_IF2 ( ) : itkObject( )
    {
        this->m_PointerToNative.Reset();
        this->m_IsDisposed = false;
        this->m_MangledTypeString = "IF2";
    }

public:
    ///<summary>Dispose of the managed object.</summary>
    ~itkMinimumMaximumImageCalculator_IF2 ( )
    {
        if (!this->IsDisposed)
        {
            this->m_IsDisposed = true;
            this->m_PointerToNative.Reset();
        }
    }

    ///<summary>Finalize the managed object.</summary>
    !itkMinimumMaximumImageCalculator_IF2 ( )
    {
        if (!this->IsDisposed && this->DisposeNativeObjectOnFinalize)
            delete this;
    }

    ///<summary>
    ///Get/set the pointer to the native ITK object associated with
    ///this wrapper instance.
    ///</summary>
    ///<returns>The pointer to the native ITK object.</returns>
    property IntPtr NativePointer
    {
        virtual IntPtr get() override { return
IntPtr(this->m_PointerToNative.Get()); }
        virtual void set ( IntPtr value ) override
        {
            this->m_PointerToNative.Reset( (NativeType*)value.ToPointer() );
        }
    }

    ///<summary>Get the last modified time.</summary>
    property unsigned long MTime
    {
        virtual unsigned long get() override { return
this->m_PointerToNative->GetMTime(); }
    }

    ///<summary>Create an instance of the underlying native itk
object.</summary>
    static itkMinimumMaximumImageCalculator_IF2^ New ( )
    {
        try
        {
            // Create a new managed object
            itkMinimumMaximumImageCalculator_IF2^ newManagedObject =
gcnew itkMinimumMaximumImageCalculator_IF2();

            // Create a new native object
            NativeType::Pointer nativeObject = NativeType::New();
            newManagedObject->m_PointerToNative.Reset( nativeObject );

            // Add AnyEvent observer
            newManagedObject->AddAnyEventObserver();

            // Return
            return newManagedObject;
        }
        catch ( itk::ExceptionObject& ex )
        {
            throw gcnew itkExceptionObject( ex.GetDescription(),
ex.GetLocation(), ex.GetFile(), ex.GetLine() );
        }
    }

    ///<summary>Return itk::LightObject::Print( ostream ) as a string.</summary>
    virtual String^ ToString ( ) override
    {
        std::stringstream ss;
        m_PointerToNative->Print( ss );
        std::string s = ss.str();
        return gcnew String( s.c_str() );
    }

    ///<summary>
    ///Remove all observers watching this object.
    ///</summary>
    ///<remarks>
    ///By default, observers are created for all events. Calling this
    ///method removes all native observers, and therefore prevents
    ///the firing of managed events. Call AddAnyEventObserver() to
    ///reset the default observers which enable the managed events.
    ///</remarks>
    virtual void RemoveAllObservers ( ) override
    {
        this->m_PointerToNative->RemoveAllObservers();
    }

    ///<summary>
    ///Adds a native observer watching for any event.
    ///</summary>
    ///<remarks>
    ///By default, observers are created for all events. Calling this
    ///method adds a single native observer for any event. This
    ///observer invokes the managed events. Therefore, calling this
    ///method more than once, or calling it without first calling
    ///RemoveAllObservers(), may cause the managed events to be
    ///invoked more than once.
    ///</remarks>
    virtual void AddAnyEventObserver ( ) override
    {
        itk::itkObjectCommand::Pointer observer = itk::itkObjectCommand::New();
        observer->SetManagedObject( this );
        this->m_PointerToNative->AddObserver( itk::AnyEvent(), observer );
    }

    ///<summary>Set the image to calculate.</summary>
    ///<param name="image">The image as an itkImage.</param>
    virtual void SetImage( itkImageBase^ image ) =
IMinimumMaximumImageCalculator::SetImage
    {
        // Some useful typedefs
        typedef NativeType::ImageType ImageType;

        // Call SetImage on the Calculator
        INativePointer^ imagePtr = safe_cast<INativePointer^>(image);
        ImageType* rawImagePtr =
reinterpret_cast<ImageType*>(imagePtr->NativePointer.ToPointer());
        this->m_PointerToNative->SetImage(rawImagePtr);

        // Reset the image requested region
        rawImagePtr->SetRequestedRegion(rawImagePtr->GetLargestPossibleRegion());
    }

    ///<summary>Set the image to calculate.</summary>
    ///<param name="itkImagePtr">The image as an IntPtr.</param>
    virtual void SetImage( IntPtr itkImagePtr ) =
IMinimumMaximumImageCalculator::SetImage
    {
        // Some useful typedefs
        typedef NativeType::ImageType ImageType;

        // Call SetImage on the Calculator
        ImageType* rawImagePtr = (ImageType*)itkImagePtr.ToPointer();
        this->m_PointerToNative->SetImage(rawImagePtr);

        // Reset the image requested region
        rawImagePtr->SetRequestedRegion(rawImagePtr->GetLargestPossibleRegion());
    }

    ///<summary>Perform the calculation.</summary>
    virtual void Compute ( ) = IMinimumMaximumImageCalculator::Compute
    {
        try
        {
            this->m_PointerToNative->Compute();
        }
        catch ( itk::ExceptionObject& ex )
        {
            throw gcnew itkExceptionObject( ex.GetDescription(),
ex.GetLocation(), ex.GetFile(), ex.GetLine() );
        }
    }

	///<summary>Set the region over which the values will be computed.</summary>
	property itkImageRegion^ Region
	{
		virtual void set ( itkImageRegion^ value )
		{
			m_PointerToNative->SetRegion(
itk::ManagedTypes::ToNativeImageRegion<NativeType::ImageType::ImageDimension>(value)
);
		}
	}

	///<summary>Gets the minimum intensity value found in the image.
NOTE: Only valid after calling Compute() or
ComputeMinimum().</summary>
	property itkPixel^ Minimum
	{
		virtual itkPixel^ get()
		{
			return itk::ManagedTypes::ToManagedPixel<NativeType::PixelType>(
m_PointerToNative->GetMinimum() );
		}
	}

	///<summary>Gets the maximum intensity value found in the image.
NOTE: Only valid after calling Compute() or
ComputeMaximum().</summary>
	property itkPixel^ Maximum
	{
		virtual itkPixel^ get()
		{
			return itk::ManagedTypes::ToManagedPixel<NativeType::PixelType>(
m_PointerToNative->GetMaximum() );
		}
	}

	///<summary>Only compute the minimum value.</summary>
	virtual void ComputeMinimum ( void ) =
IMinimumMaximumImageCalculator::ComputeMinimum
	{
		m_PointerToNative->ComputeMinimum();
	}

	///<summary>Only compute the maximum value.</summary>
	virtual void ComputeMaximum ( void ) =
IMinimumMaximumImageCalculator::ComputeMaximum
	{
		m_PointerToNative->ComputeMaximum();
	}


}; // end ref class

} // end namespace itk

#endif


2008/7/10 Bill Hoffman <bill.hoffman at kitware.com>:
> Hi Dan,
>
> Can you describe the process that managedITK uses for wrapping?  I read the
> paper, and it talks about the process being semi-automated.  Can you
> describe exactly what is automated and what is not automated?
>
> I looked at the code a bit and found each class had a cmake file with stuff
> like this:
>
> WRAP_CLASS("itk::ZeroCrossingBasedEdgeDetectionImageFilter")
>
>  WRAP_IMAGE_FILTER_REAL(2 2+)
>
>  BEGIN_MANAGED_PROPERTY("Variance" GETSET)
>    SET(MANAGED_PROPERTY_SUMMARY   "Get/set the variance parameter used by
> the G
> aussian smoothing filter in this algorithm.")
>    SET(MANAGED_PROPERTY_TYPE      "array<double>^")
>    SET(MANAGED_PROPERTY_GET_BODY  "return
> itk::ManagedTypes::ToManagedFixedArra
> y<double, NativeType::ImageDimension>( m_PointerToNative->GetVariance() );")
>    SET(MANAGED_PROPERTY_SET_BODY  "m_PointerToNative->SetVariance(
> itk::Managed
> Types::ToNativeFixedArray<double, NativeType::ImageDimension>(value) );")
>  END_MANAGED_PROPERTY()
> ...
>
> Do you have to have a managed property for each method on the class? What
> things have to go in the .cmake file for a class?  What is done by "it just
> works"?
>
> Thanks.
>
> -Bill
>


More information about the Insight-developers mailing list