14.3. Combining Two Modules in One Project

In the following chapter, we will merge our two modules (SimpleAdd and SimpleAverage) into one project, in the following steps:

Per project, one DLL (.dynlib/.so) file is created and transferred, and the modules might share common includes etc. within one project.

Therefore, this example is a showcase on how to build a larger library by augmenting an existing project.

In this example, we will merge the SimpleAverage module into the SimpleAdd project. For two modules, this is an arbitrary decision; for larger projects, always merge into the existing project.

[Note]Note

The source code of this example is not delivered with MeVisLab, as it would lead to module name collisions with the examples above. If you want to implement this example, make sure to change the module names or to move the original modules to another folder.

14.3.1. Copying the Source Files

Copy the mlSimpleAverage.cpp and mlSimpleAverage.h files to the source folder of SimpleAdd.

14.3.2. Editing and Recompiling the .pro File

  1. Open mlSimpleAdd.pro in any text editor.

  2. Add mlSimpleAverage.h to the HEADERS section.

  3. Add mlSimpleAverage.cpp to the SOURCES section.

    Make sure that the previous line is terminated with a backslash with NO whitespaces behind it. The last line does not need to be terminated by a backslash.

    Resulting code (excerpt):

    HEADERS += \
        MLSimpleAddInit.h \
        MLSimpleAddSystem.h \
        mlSimpleAdd.h \
        mlSimpleAverage.h 
    
    SOURCES += \
        MLSimpleAddInit.cpp \
        mlSimpleAdd.cpp \
        mlSimpleAverage.cpp  
  4. Recompile the .pro file (run .bat on Windows, .sh on Linux, double-click .pro on Mac).

14.3.3. Editing the Project in the Development Environment

Open the SimpleAdd project in your development environment.

14.3.3.1. Editing SimpleAverage.h

  1. Open SimpleAverage.h.

  2. Exchange the line

    #include "MLSimpleAverageSystem.h"

    by

    #include "MLSimpleAddSystem.h"

    Resulting in:

    // Local includes
    #include "MLSimpleAddSystem.h"
  3. Exchange the macro in the class definition (this handles exporting symbols under Windows)

    MLSIMPLEAVERAGE_EXPORT

    by

    MLSIMPLEADD_EXPORT

    Resulting in:

    //! Computes the average voxel value of an image.
    class MLSIMPLEADD_EXPORT SimpleAverage : public Module

    The new module in this project (i.e., SimpleAdd) needs to be initialized for the runtime-type system.

14.3.3.2. Editing MLSimpleAddInit.cpp

  1. Open MLSimpleAddInit.cpp.

  2. Add the line

    #include "mlSimpleAverage.h"

    below the line

    #include "mlSimpleAdd.h"

    Resulting in:

    // Include all module headers ...
    #include "mlSimpleAdd.h"
    #include "mlSimpleAverage.h"
  3. Add the line

      SimpleAverage::initClass();

    below the line

      SimpleAdd::initClass();

    Resulting in:

      SimpleAdd::initClass();
      SimpleAverage::initClass();

    This registers the classes to the ML runtime type system.

  4. Recompile the project.

    [Note]Note

    mlSimpleAverage.cpp does not have to be edited.

14.3.4. Editing the Module Definition (.def)

  1. Copy the file SimpleAverage.script to the folder containing the file SimpleAdd.def.

  2. Open the file MLSimpleAverage.def in MATE.

    Copy the definition of the module SimpleAverage into the clipboard (this is at least from the line

    MLModule SimpleAverage {
    to the last closing curly bracket (})

  3. Open the file MLSimpleAdd.def.

    Paste the definition of the SimpleAverage module below the definition of the SimpleAdd module.

    Exchange the line in the definition of the SimpleAverage module

    DLL = "MLSimpleAverage"

    by the line

    DLL = "MLSimpleAdd"

Resulting code:

MLModule SimpleAdd {
  DLL                = MLSimpleAdd
  genre              = ""
  author             = "JDoe"
  comment            = "Adds a constant double value to each voxel."
  keywords           = ""
  seeAlso            = Arithmetic1
  exampleNetwork     = $(LOCAL)/networks/SimpleAddExample.mlab
  externalDefinition = $(LOCAL)/SimpleAdd.script
}

MLModule SimpleAverage {
  DLL                = MLSimpleAdd
  genre              = ""
  author             = "JDoe"
  comment            = "Computes the average voxel value of an image."
  keywords           = "Statistics Average"
  seeAlso            = ""
  exampleNetwork     = $(LOCAL)/networks/SimpleAverageExample.mlab
  externalDefinition = $(LOCAL)/SimpleAverage.script
}

14.3.5. Cleaning up Folders and Example Networks

  1. Copy the example network and HTML documentation of the SimpleAverage module to the according folders of the SimpleAdd module. The paths to those files should be relative, so they are still correct.

  2. (Re)move the old files and folders of the SimpleAverage module from the folders /Sources and /Modules so that no conflicts arise.

  3. (Re)start MeVisLab.

    Both modules can now be added, for example via a quick search. However, you will find that in the About information, the same DLL will appear for both modules.