The class Host manages the entire image
        processing in the ML including paging, caching, parallelization and
        calling any Module::calculate* functionality. It
        also provides functions such as checking and updating module graphs as
        well as calculating (sub)images with getTile()
        commands.
The Host processes a set of ML modules
        that are derived from the class Module and
        connected as a directed acyclic graph.
![]()  | Note | 
|---|---|
Do not try to use the   | 
For memory-optimized calculation of an image or subimage, each
        ML module (derived from Module) supports
        so-called page-based image processing, i.e., each
        image is divided into blocks (called pages) which
        are then processed sequentially or in parallel and are finally
        combined to the requested (sub)image.
Consequently, the memory usually does not hold the complete image, but only the currently used fragments.
The page extent is defined as an image property of each ML module output. Page-based image processing can degenerate to global image processing when the page extent is set to the extent of the actual image. This, however, is the worst case and should be avoided.
During image processing, the ML stores as many pages as possible
        in the cache of the MLMemoryManager (Section 1.3.2.2, “The MLMemoryManager and Memory Handling”) to reach maximum performance. Repeated
        (sub)image requests can often be processed more efficiently by simply
        reusing existing pages. The extent of pages can be controlled by the
        application or by the user.
Overview of image requests performed by the
        Host:
1. Viewer shows image properties and data
        from Filter.
2. Filter calculates results from image
        properties and data from Load.
The Host remains invisible to the module
        but processes all Viewer requests. Functions
        (e.g., getTile()) are wrapped in the class
        Module:
When a tile is requested, the tile request is broken down into page request:
Host calculates a tile with
        getTile() as follows:Allocate memory for the tile.
Calculate the pages that are intersected by the tile.
For all pages:
Already in cache? Yes => Done.
Not in cache? => Allocate page in cache.
Request to Filter with
                calculateInputSubImageBox(): Determine input area
                needed to calculate the page.
Allocate and calculate the input tiles by recursively
                calling getTile().
Call calculateOutputSubImage() in
            Filter.
Copy pages to tile.
The ML class Memory provides functions
        for memory allocation, reallocation, freeing, etc. Currently, only
        basic functionality is available; however, future versions will use
        automatic strategies to (re)organize and/or clean up memory (and the
        ML cache) to reduce or avoid out-of-memory errors.
![]()  | Important | 
|---|---|
If possible, always try to use the memory handling functionality of this class when you need to allocate your own memory. This class can automatically handle memory errors and will support correct and safe memory handling in the future.  | 
![]()  | Note | 
|---|---|
You can use the   | 
![]()  | Note | 
|---|---|
See Section 5.5, “Tracing, Exception Handling and Checked Object Construction/Destruction” for alternative memory management concepts.  | 
The following class functionality is currently available:
static void* allocateMemory(MLuint size, MLMemoryErrorHandling handleFailure);
Allocates a memory block of size
            bytes.
static void* reallocateMemory(void* ptr, MLuint size, MLMemoryErrorHandling handleFailure);
The memory block pointed to by ptr is
            resized and copied so that it has at least
            size bytes.
static void freeMemory(void* ptr);
Frees memory that has been allocated with any
            Memory function. NULL pointers may be
            passed safely; they are simply ignored.
static void* duplicateMemory(const void *ptr, MLuint size, MLMemoryErrorHandling handleFailure);
Copies the memory pointed to by src
            of size size in a newly allocated buffer
            which must be freed by the caller with
            freeMemory(). If ptr
            is passed as NULL, NULL
            is returned without any error handling.
static char* duplicateString(const char *ptr, MLMemoryErrorHandling handleFailure);
Copies the passed null-terminated string
            str in a newly allocated buffer which must
            be freed by the caller with
            freeMemory().
![]()  | Note | 
|---|---|
Always use functions of the class
              | 
The parameter handleFailure determines
        the function behavior in error cases:
If memory allocation fails, NULL is
            returned without error handling. The programmer must take care of
            the error.
If memory allocation fails,
            ML_PRINT_FATAL_ERROR() with error code
            ML_NO_MEMORY is called;
            NULL is returned if
            ML_PRINT_FATAL_ERROR() has been returned. The
            programmer does not need to take care of the error case, because
            the ML handles it.
If memory allocation fails,
            throw(ML_NO_MEMORY) is executed. The
            programmer could implement something like
Example 2.4. Using Exceptions when Allocating Memory with MLThrowNoMemory
ML_START_NAMESPACE
  try {
    // Try to allocate...
    Memory::allocateMemory(1000, ML_THROW_NO_MEMORY);
  }
  catch(MLErrorCode)
  {
    // Handle error if memory could not be allocated.
  }
ML_END_NAMESPACENote that these error handling cases will only occur if the
        Memory class functionality has no chance to
        allocate the required memory. In future versions, the following might
        happen: The first internal allocation fails, but the
        Memory class clears the ML cache and
        successfully retries memory allocation. In those cases, none of the
        above error cases will be used.
The 
            ml::Base
           class is a base class of many ML classes and is designed for all
        objects passed between different ML modules via the so-called
        Base fields. Thus it is possible to establish
        transfer of arbitrary data types between modules.
The ML provides a so-called Runtime Type System for managing all important classes available in the module database and in the ML.
This class contains the global runtime type system of the
            ML. It manages a dictionary of runtime types and can create and
            remove runtime types. This class only contains static components
            and must be initialized with
            
                 and destroyed
            with init()
              
                destroy(). 
              
This class contains runtime-generated type and inheritance
            information of associated classes. To track this information, the
            macros defined in 
                mlRuntimeSubClass.h
               have to
            be inserted in the declaration and implementation of the
            associated classes.
This class manages a set of instances of the class
            RuntimeType. The class
            Runtime uses one global instance of this
            class for the runtime type system of the ML.
The file 
            mlRuntimeSubClass.h
           also includes
        important and frequently used macros.
ML_BASE_IS_A(base,type)
This macro is used to check whether the given
            Base pointer is of the expected type:
            ML_BASE_IS_A(base, MarkerExample).
![]()  | Note | 
|---|---|
The macro   | 
 Base must be used.Each of these macros implements the interface to the runtime type system of the derived class.
ML_CLASS_HEADER(className)
This macro must be included in the header of a non-abstract class to declare some additional methods described below.
ML_MODULE_CLASS_HEADER(ModuleClassName)
This macro must be included in the header of a class
              derived from the class
              
                  Module
                 to declare some
              additional methods described below.
ML_ABSTRACT_CLASS_HEADER(className)
This macro must be included in the header of an abstract class to declare some additional methods described below.
One of the following macros in the source file implementation of
        a class derived from Base must be used.
Each of these macros implements the interface to the runtime type system of the derived class.
ML_CLASS_SOURCE(className, parentName)
This macro must be included in the source file of a
            non-abstract class to implement the methods declared with
            ML_CLASS_HEADER.
ML_MODULE_CLASS_SOURCE(className, parentModule)
This macro must be included in the source file of classes
            derived from the class Module to implement
            the methods declared with
            ML_MODULE_CLASS_HEADER.
            Module implements protected constructors
            and assignment operators to avoid the assignment of
            Module modules to themselves. The normal
            ML_CLASS_SOURCE macros cannot be used.
ML_ABSTRACT_CLASS_SOURCE(className,parentName)
This macro must be included in the source file of an
            abstract class to implement the methods declared with
            ML_ABSTRACT_CLASS_HEADER.
ML_MODULE_CLASS_SOURCE_EXT(className, parentModule, superClassConstructs)
This macro is an alternative to
            ML_MODULE_CLASS_SOURCE if the constructor of
            the parentModule does not have two
            parameters or if other members need to be initialized (e.g.
            constants). The third parameter
            superClassConstructs permits the
            specification of the correct constructor call of the superclass,
            e.g., ML_MODULE_CLASS_SOURCE_EXT(MyFilter, MyParentModule, :MyParentModule()) does not pass
            parameters for the superclass constructor that is used in the
            normal Module.
If you need to pass more complex expressions as third parameters, such as superclass or member initializers (as a comma-separated list, for example), use the following trick:
Example 2.5. How to Use the Macro ML_MODULE_CLASS_SOURCE_EXT
// Stuff to do for base classes when copy constructor is implemented
// (which is done in a macro to have a private and not an executable
// copy constructor).
#define _INIT_STUFF : Module(0,0), _initMember1(initValue1), \
                                   _initMember2(initValue2)
// This macro declares some automatically generated functions and methods
// for the runtime system and for the initialization of this class. It
// implements more elaborated superclass and member initializers given
// by _INIT_STUFF.
ML_MODULE_CLASS_SOURCE_EXT(MyNewModule, Module, _INIT_STUFF)
#undef _INIT_STUFFSee also the file 
            mlLibraryInitMacros.h
          
        which does not directly belong to the runtime type system but which
        contains macros for the initialization after runtime linking to the
        library. It permits the implementation of a function in a library
        where module classes and runtime types can be initialized directly
        after linking to the library.
See Chapter 5, Debugging and Error Handling for detailed information on concept, classes and macros for error handling and debugging.
          © 2025 MeVis Medical Solutions AG