Initializing help system before first use

# Defining constants

Topics covered in this chapter:

- Example
- Structures for passing information
  - List of constants
  - Interface structure
  - Initialization function
- Complete module example
- Module vs. package

Several models might share a set of constants (such as mathematical constants or text strings to obtain nicely formatted output). Defining these constants in a module that is loaded by every model makes a repetetion of the definitions in every single model unnecessary.

## Example

Below we show how to define constants of different types (integer, real, string, Boolean). Once this module with the name myconstants is completed, we can write a simple model to output the constants:

    model "test myconstants module"
     uses "myconstants"

     writeln(MYCST_LINE)
     writeln("BigM value: ", MYCST_BIGM, ", tolerance value: ", MYCST_TOL)
     writeln("Boolean flags: ", MYCST_FLAG, " ", MYCST_NOFLAG)
     writeln(MYCST_LINE)

    end-model

The result that we expect to see printed is the following:

    ----
    BigM value: 10000, tolerance value: 1e-05
    Boolean flags: true false
    ----

Without the need to write such a test program, we could use the Mosel command

    examine myconstants

which will list all constants and (if there were any) subroutines, types and parameters, defined by the module myconstants.

To prevent name clashes between constants that are provided by different modules, a good habit to get into is to use prefixes (e.g. based on the module name) in the names of constants, as is done in the following example.

## Structures for passing information

A module that merely defines constants does not require any specific information to be passed from Mosel into the module. For the information flow from the module to Mosel, that is to make the constants defined in the module known to Mosel, certain predefined structures must be used. These structures are defined in the header file xprm_ni.h which must be included by every module source file (no other Mosel header files are required):

    #include "xprm_ni.h"

### List of constants

The list of the constants and their definitions must be contained in a structure of type XPRMdsoconst:

     static const double tol=0.00001;
     static XPRMdsoconst tabconst[]=
        {
         XPRM_CST_INT("MYCST_BIGM", 10000),        /* A large integer value */
         XPRM_CST_REAL("MYCST_TOL", tol),          /* A tolerance value */
         XPRM_CST_STRING("MYCST_LINE",             /* String constant */
         "----"),
         XPRM_CST_BOOL("MYCST_FLAG", XPRM_TRUE),     /* Constant with value true */
         XPRM_CST_BOOL("MYCST_NOFLAG", XPRM_FALSE)   /* Constant with value false */
        };

In this list, the type of a constant is indicated by the macro name XPRM_CST_type. The example shows all possible types: integer, real, string, and Boolean. The first parameter of the macro is the name of the constant (in a Mosel program), the second its value. Note that double (Mosel's real) constants cannot be defined immediately in this structure, their value must be given through a C variable of type static const double.

### Interface structure

The list of constants is then included in the interface structure. The interface structure takes the lists of constants, subroutines, types, and services (in this order) in the form of pairs size, list (every list is preceded by its size):

    static XPRMdsointer dsointer=
        {
         sizeof(tabconst)/sizeof(XPRMdsoconst), tabconst,
         0, NULL,
         0, NULL,
         0, NULL
        };

### Initialization function

The main exchange of information between the new module and Mosel takes place in the module initialization function. The format and the name of this function are fixed by Mosel:

    DSO_INIT myconstants_init(XPRMnifct nifct, int *interver,int *libver,
                              XPRMdsointer **interf)
    {
     *interver=XPRM_NIVERS;     /* Mosel NI version */
     *libver=XPRM_MKVER(0,0,1); /* Module version */
     *interf=&dsointer;         /* Pass info about module contents to Mosel */
     return 0;
    }

The function name serves to identify this function as the one that initializes the module. It must consist of the module name followed by _init. With the first function parameter, Mosel passes the list of its Native Interface (NI) functions into the module (not used by this module). These functions correspond largely to the functions of the Mosel Run Time Library, with some additional functions for modifying the model data. The remaining parameters must be filled by the module: the current Mosel Native Interface version, the version number of the module and the interface structure with all the items that are to be made known to Mosel. We set the module version number to 0.0.1. If a model file is compiled into a binary model file with this version of the module, the binary model file can be run with any version 0.0.n of the module, where n≥ 1.

## Complete module example

Below follows the complete listing of the program that implements the myconstants module.

    #include <stdlib.h>
    #include "xprm_ni.h"

    static const double tol=0.00001;

    /* List of constants */
    static XPRMdsoconst tabconst[]=
        {
         XPRM_CST_INT("MYCST_BIGM", 10000),   /* A large integer value */
         XPRM_CST_REAL("MYCST_TOL", tol),     /* A tolerance value */
         XPRM_CST_STRING("MYCST_LINE",        /* String constant */
         "----"),
         XPRM_CST_BOOL("MYCST_FLAG", XPRM_TRUE),     /* Constant with value true */
         XPRM_CST_BOOL("MYCST_NOFLAG", XPRM_FALSE)   /* Constant with value false */
        };

    /* Interface structure */
    static XPRMdsointer dsointer=
        {
         sizeof(tabconst)/sizeof(XPRMdsoconst), tabconst,
         0, NULL,
         0, NULL,
         0, NULL
        };

    /* Module initialization function */
    DSO_INIT myconstants_init(XPRMnifct nifct, int *interver,int *libver,
      XPRMdsointer **interf)
    {
     *interver=XPRM_NIVERS;     /* Mosel NI version */
     *libver=XPRM_MKVER(0,0,1); /* Module version */
     *interf=&dsointer;         /* Pass info about module contents to Mosel */

     return 0;
    }

## Module vs. package

Identical functionality and behavior to what is provided by our module myconstants may be obtained from a package. The implementation of package myconstants (see Mosel User Guide, chapter 'Packages' for further explanation) takes less than 10 lines of Mosel code, making our C implementation appear unnecessarily complicated for the definition of a few constants:

    package myconstants

     public declarations
      MYCST_BIGM = 10000          ! A large integer value
      MYCST_TOL = 0.00001         ! A tolerance value
      MYCST_LINE = "----"         ! String constant
      MYCST_FLAG = true           ! Constant with value true
      MYCST_NOFLAG = false        ! Constant with value false
     end-declarations

    end-package

Parent Topic Mosel Native Interface User Guide

© 2001-2026 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.