Une donnée fonctionnelle est une connaissance sur le système qui s'exprime, non pas par une valeur numérique ou symbolique, scalaire ou vectorielle, donnée à un attribut du système, mais par une fonction. Une fonction renvoie une valeur (scalaire ou vectorielle) et/ou réalise un effet de bord sur certains attributs du système. Ce que fait la fonction est déterminé par l'état du système et de son environnement au moment de l'invocation.
Le développeur d'un simulateur sous DIESE peut coder une connaissance fonctionnelle, par exemple pour une entité, de deux manières différentes :
- Créer une sous-classe de Method, puis en attacher une instance à l'entité par AddMethod. La sous-classe peut être dotée d'un corps dans le constructeur, mais ce corps peut être ensuite "surchargé" (remplacé) par un autre (par AssignBody). Dans les deux cas, le corps est une fonction C++ classique déclarée et réalisée dans les fichiers de l'application (par exemple UserEvent.cc, *.h pour les événements).
Ce n'est pas le cas de la classe Entity, mais on sait que certaines classes de base de DIESE (Event, par exemple) sont dotées de méthodes prédéfinies : DIESE impose leur identité (symbole et nom de classe) et les affecte automatiquement aux instances des classes. Pour leur adjoindre une méthode non prédéfinie, le développeur doit en coder lui-même le constructeur (et par là-même décider de l'identité de la méthode), puis invoquer explicitement AddMethod dans le constructeur de la classe dont la méthode est un attribut fonctionnel.- Doter l'entité, pour suivre cet exemple, d'une fonction membre, au sens des langages à objets. La fonction est déclarée dans la partie publique ou privée de la classe et réalisée par ailleurs. Si le membre déclaré possède le type 'pointeur sur une fonction' (appelons-le {small (* m)}), alors le développeur peut lui affecter comme valeur une fonction (disons {small f}) écrite par ailleurs (par {small m = f}).
Dans les deux cas, le corps de fonction codant la connaissance fonctionnelle est compilé puis intégré dans le module exécutable (le simulateur). Il est clair que toute modification du code passe par les étapes de compilation et d'intégration à l'exécutable (édition des liens).
Cette page expose les procédures d'externalisation de données fonctionnelles. L'externalisation, c'est le placement du corps des fonctions correspondantes à l'extérieur du module exécutable et l'établissement d'un pont entre les deux. Par ce pont transitent des commandes (l'exécutable invoque une fonction externe et la fonction invoque des services de DIESE) et des données (l'exécutable passe des arguments à la fonction externe et la fonction lui renvoie un résultat ou modifie par effet de bord la valeur de variables dans l'espace d'adressage de l'exécutable). Il est important de noter deux choses :
- Seules les connaissances codées par des instances de la classe Method peuvent être externalisées, à l'exclusion de celles codées par des fonctions membres.
- Le code externalisé n'est pas compilé, c'est-à-dire qu'il est pris en charge par un interpréteur. La présente version de DIESE supporte des connaissances externalisées codées en perl.
Dans la suite, on indique d'abord que les procédures d'externalisation requièrent une version de DIESE appropriée. Puis on décrit ce qu'il faut changer dans le code d'un simulateur existant pour externaliser une fonction. On donne au passage quelques règles d'écriture de la version perl de la fonction. Enfin, on décrit ce qu'il faut faire pour que ce code perl puisse intégrer des appels à des services de DIESE. Dans ce dernier point intervient l'outil SWIG.