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.
© 2001-2020 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.