Module version
Modules that are developed and distributed over a longer period of time most likely will have gone through a number of versions— the reader is reminded that the module version number is returned in the argument libver of the module initialization function and can be generated with the help of the NI macro XPRM_MKVER. Functionality added by a given module version will obviously not be available from older versions, and inversely, models written for older module versions will not require this new functionality. So, depending on the functionality used by a given model, we may be required to use a more or less recent version of a given DSO (NB: the expected module version is stored in the BIM file).
Furthermore, depending on the conventions used for numbering a particular module, the default module version compatibility rules applied by Mosel may have to be modified for a particular module.
'Update version' service
The service XPRM_SRV_UPDVERS makes it possible to determine which module version is required by a model by inspecting the module functionality used in this particular model. This services is used by the Mosel compiler (whereas most other services are used at runtime). The DSO will be loaded with the lowest version number that satisfies the functionality required be the model. As a consequence, it is possible update the DSO to some newer version (containing additional functionality and maintaining all existing) without having to recompile the model source.
Example: Assume that we have implemented a new version 0.0.2 of the example 'solarray' from Chapter User-defined subroutines that defines an additional overloaded form of the subroutine 'getsol' returning solution values rounded to integers. That is, we now have the following two entries in the list of subroutines:
static XPRMdsofct tabfct[]= { {"solarray",1000,XPRM_TYP_NOT,2,"A.vA.r",ar_getsol}, {"solarray",1001,XPRM_TYP_NOT,2,"A.vA.i",ar_getintsol} };
To implement detailed module version checking, we define the list of services with a single entry for the XPRM_SRV_UPDVERS service, and we update the main interface definition structure correspondingly:
/* Table of services */ static XPRMdsoserv tabserv[]= { {XPRM_SRV_UPDVERS,(void*)updvers}, /* Module version check */ }; /* Interface structure */ static XPRMdsointer dsointer= { 0,NULL, sizeof(tabfct)/sizeof(XPRMdsofct),tabfct, 0,NULL, sizeof(tabserv)/sizeof(mm_dsoserv),tabserv };
The function updvers returns the required module version depending on the input it receives in its arguments event (XPRM_UPDV_INIT = called at module initialization, returns the lowest version counter for this module; XPRM_UPDV_FUNC = checking the module version required by a particular subroutine) and what (identification number of the object for subroutines, types, parameters).
static void updvers(int event, int what, int *version) { if (event==XPRM_UPDV_INIT) *version=XPRM_MKVER(0,0,1); /* First version of this module */ else if (event==XPRM_UPDV_FUNC) { switch (what) { case 1000: *version=XPRM_MKVER(0,0,1); /* Works with 1st module version */ break; case 1001: *version=XPRM_MKVER(0,0,2); /* Requires 2nd module version */ } } }
A model that is compiled using the new module version 0.0.2, but that just uses the original real-valued getsol function will load the module as version 0.0.1.
'Check version' service
The service XPRM_SRV_CHKVER allows a module to override Mosel's default version compatibility rules that are checked at runtime when loading the module: module version numbers use a code with 3 numbers (major, minor, release); by default, a module version A can be used in place of module version B if the following conditions apply
minor(A) = minor(B)
release(A) ≥ release(B)
Example: Instead of numbering our extension of the 'solarray' example described in the previous section as version 0.0.2, we wish to give it the version number 0.1.0. That is, we now have the following module initialization function:
DSO_INIT solarray_init(XPRMnifct nifct, int *interver,int *libver, XPRMdsointer **interf) { ... *libver=XPRM_MKVER(0,1,0); /* Module version */ ... }
The compilation of models requiring the previous version 0.0.1 will work correctly with the corresponding definition of the 'update version' service. However, loading of the generated BIM file will fail with the error message 'wrong version for module solarray' if the default compatibility rules are applied. The following definition of the XPRM_SRV_CHKVER service will make it possible to use a module version 0.1.0 with a model that expects a DSO version 0.0.*, for completeness' sake we also show the definition of function updvers:
/* Table of services */ static XPRMdsoserv tabserv[]= { {XPRM_SRV_UPDVERS,(void*)updvers}, {XPRM_SRV_CHKVER,(void*)chkvers}, }; static void updvers(int event, int what, int *version) { if (event==XPRM_UPDV_INIT) *version=XPRM_MKVER(0,0,1); /* First version of this module */ else if (event==XPRM_UPDV_FUNC) { switch (what) { case 1000: *version=XPRM_MKVER(0,0,1); /* Works with 1st module version */ break; case 1001: *version=XPRM_MKVER(0,1,0); /* Requires 2nd module version */ } } } static int chkvers(int reqvers) { /* This module version accepts to run with models expecting any version from 0.0.1 to 0.1.0 inclusive */ return (reqvers>MM_MKVER(0,1,0))||(reqvers<MM_MKVER(0,0,1)); }