INTERFACER DES ROUTINES EXTERNES AVEC MUSTIG

tableau des matières

5-1. Introduction

5-1-1. Le principe

5-1-2. Contraintes sur le code externe

5-2. Définir l'interface dans MUSTIG

5-2-1. Le module Extern

5-2-2. Définir la fonction des bornes sur le module Extern

Entrer le texte de l'interface

Les modes d'appel facultatifs

5-2-3. Code d'interface ajouter à la DLL

Pointeurs utilisés pour se référer au tableau de données

Le tableau des paramètres :

Se référer aux données dans le code C externe

5-2-4. Exemple de routine externe interfacée en C et Fortran

Description de l'algorithme

La routine C externe

La routine Fortran externe

5-3. Le cas spécial Macintosh

5-3-1. Macintosh 680xx

Cas spécial Fortran

5-3-2. Power Macintosh

5-4. Les cas spéciaux UNIX

5-4-1. Le processus de mémoire partagée

Le principe

Les exemples

Compiler la routine externe

5-4-2. Le processus de chargement dynamique

La gestion de la mémoire

Créer les routines externes " .dll "

5-5. Les cas spéciaux Windows

5-6. PC + AU32

Les options AU32 spéciales

Créer la routine externe .tms pour la carte AU32

 

 

 

 

5. Interfacer des routines externes avec MUSTIG

5-1. Introduction

5-1-1. Le principe

Les routines externes peuvent être appelées à partir d'un graphe MUSTIG :

Les données d'entrée (par exemple signaux, paramètres numériques, chaînes, description de variable) sont définies dans MUSTIG et sont passées à la routine externe. Cette dernière traite les données incidentes et produit des données de sortie qui sont rendues à MUSTIG pour traitement ultérieur ou affichage.

Les données de sortie n'ont pas forcément la même structure que les données d'entrée. Par exemple, vous pouvez définir un signal 2D, plus un vecteur de paramètres, plus une chaîne comme paramètres d'entrée, et produire seulement un scalaire sur la sortie.

Cela permet d'utiliser des routines pernonnelles existantes sans devoir les récrire complètement en langage MUSTIG. Certains algorithmes sont écrits dans un langage procédural comme C plus facilement que dans MUSTIG. Dans ce cas, ce peut être une meilleure idée de créer et interfacer une routine externe, que de construire un graphe MUSTIG qui fait le même travail.

5-1-2. Contraintes sur le code externe

Sur quelques machines (par exemple Macintosh 680xx ou Sun/OS), le code doit avoir seulement un point d'entrée : vous ne pouvez pas utiliser des DLLs d'entrée multiple .

Bien sûr, le code a besoin d'être modifié légèrementpour autoriser la communication d'entrée et de sortie avec MUSTIG (voyez Définir l'interface dans le code externe).

5-2. Définir l'interface dans MUSTIG

5-2-1. Le module Extern

Le module de l'interface externe est disponible dans la section <-> de la bibliothèque:

permet de connecter un programme C avec MUSTIG

permet de connecter un programme Fortran avec MUSTIG

Le module a initialement 8 bornes, comptées de 1 à 8 comme les aiguilles d'une montre:

Vous pouvez ajouter ou enlever des bornes si nécessaire (voyez Créer une borne et Effacer une borne): les bornes sont renumérotées comme les aiguilles d'une montre, en commençant à la borne la plus basse sur le bord gauche du module.

La structure des données d'entrée et de sortie sera décrite comme un texte entré dans la face avant du module. Vous pouvez redimentionner le module si nécessaire. Chaque borne peut être utilisée comme une borne d'entrée ou comme une borne de sortie, selon comme c'est indiqué dans le texte.

5-2-2. Définir la fonction des bornes dans le module Extern

Entrer le texte de l'interface

  1. Reliez les fils d'entrée et de sortie au module Extern. Un exemple est montré ci-dessous :
  2. Vous choisissez maintenant le type et structure des données sur chaque borne.

     

  3. Entrez le nom de la routine sur la face avant du module Extern (taper Maj+Ctrl+Clic pour entrer en mode d'édition), seulement au dessous du mot " Extern ".
  4. Si ce nom est My_Subprog par exemple, MUSTIG cherchera une routine externe nommée My_Subprog, My_Subprog.sub ou My_Subprog.dll dans le répertoire courant en premier, et puis dans les répertoires spécifiés par l'utilisateur dans Edition / Options / Chemins et dans les variables d'environnement.

    Le nom peut être aussi une entrée dans une DLL d'entrée multiple (si disponible sur votre machine). Par exemple, le nom

    My_dll@My_Routine

    fait référence à une routine nommée My_Routine dans la DLL nommée My_dll.dll.

     

  5. Décrivez les données sur chaque borne connectée. Une ligne par borne, d'après la syntaxe décrite ci-dessous :

<numéro de borne><direction><type de donnée>[<variable(s) associée(s)>]

 

Champ

Valeurs possibles

Fonction

<numéro de la borne>

1 à nombre de bornes total

Numéro de la borne (voir Le module Extern)

<direction>

+ : borne de sortie

- : borne d'entrée

Définit la direction de la borne (entrée ou sortie)

<ype des données>

I1,I2, I4 pour les nombres entiers,

R4, R8 pour les réels,

C8, C16 pour les complexes,

W pour un plan graphique

S pour une chaîne

X type indifférent (voir ci-dessous)

Définit le type des données sur la borne.

Voir les exemples livrés avec Mustig pour une démonstration de comment un plan graphique doit être traité.

<variable(s) associée(s) >

Si les données ne sont pas scalaires, le nom de la(des) variable(s) est spécifié après un signe ' / ' comme d'habitude.

 

Le type X " indifférent ":

Si la routine externe produit un signal de sortie (c.-à-d. un vecteur, une matrice, un signal 3D,…), ce signal doit être porté par au moins une variable. Si le signal de sortie a exactement les même attributs qu'un signal d'entrée, le même nom de variable peut être utilisé (voir les Attributs d'une variable).

Cependant, si les attributs d'un signal de sortie sont différents de ceux d'un des signaux d'entrée, une description de variable appropriée doit être entrée sur une borne d'entrée du module Extern. La ligne associée sur la face avant du module est entrée avec un type égal à X, signifiant que seulement les attributs de la variable sont utilisés, et non les données qu'il porte s'il y en a.

Dans l'exemple précité, la DLL externe est appelée avec deux scalaires comme données d'entrée, et retourne un vecteur. L'utilisateur doit dire ce que sont les caractéristiques du vecteur produit à MUSTIG, en ajoutant une borne d'entrée (borne #3 ici) suivi à une description variable avec les attributs appropriés. Cette description peut être ramassée d'un signal existant: seulement les attributs seront utilisés, pas les données elles-mêmes.

S'il vous plaît notez qu'une " borne X " ne doit pas être référencée dans le code DLL externe, elle est utilisée par Mustig seulement.

 

Exemple

Si on suppose que le scalaire de la sortie est un nombre réel, le texte de l'interface pour l'exemple présenté dans le paragraphe 1 pourrait être :

Autres exemples de lignes d'interface valides

1-C8/x/y

La borne #1 est une borne d'entrée, portant des données complexes de simple précision distribuées comme un 2D signal selon les variables x et y.

3-X/u

La borne #3 est une borne d'entrée, portant la description d'une variable nommée u. Cette variable sera utilisée pour construire un signal de sortie.

6+S

La borne #6 est une borne de sortie qui rend une chaîne du caractère

1-W

La borne #1 est une borne d'entrée portant un plan graphique

4+I2/t

La borne #4 est une borne de sortie qui rend un vecteur de nombres entiers de 2 octets selon une variable nommée t.

Les modes d'appel facultatifs

Suivant la description des bornes dans le texte de l'interface, l'utilisateur peut entrer une ou les deux des lettres suivantes :

IX

Habituellement, si la mémoire disponible est insuffisante pour traiter un signal, la routine externe peut être appelée plusieurs fois par Mustig. Si le drapeau X est présent dans le texte de l'interface, ce processus est mis hors fonction.

Utilisez ce drapeau quand connecter MUSTIG avec les routine d'acquisition de données.

5-2-3. Code d'interface à ajouter à la DLL

Le processus d'interfaçage d'une routine externe avec MUSTIG a été décrit ci-dessus du point de vue de MUSTIG.

Dans cette section, nous décrivons comment l'interface est écrite du point de vue du code  externe : le code externe doit savoir où sont les données d'entrée et où entreposer les résultats de la sortie. Cette section exige que le lecteur soit familier avec les notions de pointeur et adresse mémoire.

Bien sûr, le nom des pointeurs et variables peut être différent de ceux présentés dans les sections suivantes. Vous êtes libre de choisir des noms plus explicites, ou plus compacts si vous souhaitez.

Les pointeurs utilisés pour faire référence au tableau des données

Quand on entre dans la routine externe, le stack contient trois pointeurs :

Nom

Pointe sur

Fonction

t

La tableau des données de Mustig

Première adresse du tableau des données

p

Tableau des paramètres (voir ci-dessous)

Fait référence aux bornes

r

Une chaîne de 80 caractères

Message d'erreur à retourner

La tableau des paramètres :

La tableau de paramètres est constitué de nombres entiers 32 bits.

Langage C : La tableau des paramètres est déclaré comme une structure p de nombres entiers longs, et les éléments décrits ci-dessous sont les composants de la structure. (voir l'exemple).

Langage Fortran : La tableau de paramètres p et ses composants (c.-à-d. les variables listées ci-dessous) est déclaré comme variables de integer*4. Pour chaque borne, l'utilisateur appelle un sous-programme spécifique nommé mstg#v # remplace le nombre de variables sur la borne (voir l'exemple)

Nom de Var.

Fonction

i

Index réservé (initialisé à 2)

nb_pins

Nombre de bornes connectées- permet de vérifier que le nombre de bornes connectées est correct - Si le nb_pins est trouvé égal à 0, cela veut dire que l'option " I " a été entrée dans le texte de l'interface du module Extern et la routine externe est appelée à nouveau quand les calculs sont finis (voir les modes d'appel facultatifs). Les bornes déclarées comme ayant le type X dans le module Extern ne sont pas incluses dans ce compte.

Nom de Var.

Fonction

nvar #

Nombre de variables (ou dimensions) portées par la borne :

    • Scalaire : 0
    • Vecteur : 1
    • Matrice ou groupe de signaux 1D : 2
    • Signal 3D : 3, etc.,

d #

Place dans la tableau des données pointée par le pointeur t.

Nom de Var.

Fonction

in#

Un incrément entre valeurs consécutives selon la variable

n #

Nombre d'échantillons selon cette dimension

 

Exemple de déclaration de variable potentielle :

nvar0, d0,

La borne #0 porte un scalaire. Donc, nvar0 sera mis à 0 (aucune variable) par Mustig en appelant la routine externe. Nous recommandons que cela soit vérifié dans votre code.

nvar1, d1, in1, n1,

La borne #1 porte un vecteur (c.-à-d. le signal a une variable là). Donc les nvar1 seront mis à 1 par Mustig.

nvar2, d2, in2, n2, in21, n21,

La borne #2 porte une matrice (c.-à-d. le signal a deux variables là). Donc, les nvar2 seront mis à 2.

nvar3, d3, in3, n3, in31, n31, n32, in32,,

La borne #3 porte un signal 3D (c.-à-d. le signal a trois variables là). Donc, les nvar2 seront mis à 3.

Note : Dans ces déclarations de variables, les bornes sont comptées de 0 à Npins -1. Vous pouvez changer ceci et comptez la borne de 1 à Npins si vous voulez. Juste changez les noms de variables en conséquence. Les noms des variables ne sont pas utilisés comme mots-clé, donc vous pouvez leur donner les noms que vous voulez.

Faire référence aux données dans le code C externe

Le pointeur t peut être vu comme l'adresse du premier élément d'un grand segment de mémoire : le tableau de données Mustig .

Les données portées par chaque borne (soit entrée soit sortie) sont accédées en utilisant les variables précédemment déclarées d# (voir Le tableau des paramètres) qui donnent le décalage dans le tableau des données pour chaque borne :

Cas 1 : la borne porte un scalaire

valeur = * (t + p->d0);

"valeur" est une variable du même type que celle déclarée pour la borne dans le texte de l'interface sur le module Extern Mustig. Autrement, les conversions automatiques seront faites par votre ordinateur et le résultat peut ne pas être bien portable aux autres machines.

* (t + p->d0) = valeur;

* (t + p->d0) = 0.5213;

Note : Vous pouvez utiliser aussi des variables intermédiaires et des pointeurs pour faire référence à la borne, si vous trouvez cela plus lisible :

int *pin_0; / * déclare un pointeur intermédiaire * /

pin_0 = (t + p->d0); / * cela réfère à la borne #0 * /

valeur = *pin_0; / * lu si c'est une borne d'entrée * /

pin_0 = valeur; / * ou écrit si c'est une borne de sortie * /

 

Cas 2: la borne porte un vecteur

Supposez que la borne #0 porte un vecteur. Un segment de mémoire est donné à ce vecteur, qui commence à l'adresse

t + p->d0

Cette adresse correspond au premier élément du vecteur. Pour lire ou écrire les autres éléments du vecteur, utilisez l'incrément de variable précédemment déclaré in# qui donne le nombre d'octets entre deux éléments consécutifs du vecteur:

t + p->d0

Adresse du premier élément = vector[0]

t + p->d0 + in0

Adresse du deuxième élément = vector[1]

t + p->d0 + n*in0

Adresse de l'élément énième = vector[n]

Exemples:

val = * (t + p->d0 + 2*in0)

Une variable précédemment déclarée nommée val est mise à la valeur du troisième élément du vecteur sur la borne d'entrée 0.

* (t + p->d0 + 2*in0) = val

Le troisième élément du vecteur sur la borne de sortie 0 est mise à la valeur de la variable val .

vecteur = t+p->d0

Le pointeur 1D vecteur est associé à la borne 0

 

Cas 3: la borne porte une matrice

Suivant le même principe, si la borne porte une matrice, vous pouvez faire référence à tout élément en utilisant les incréments de variables sur les deux dimensions. Utilisez cette adresse pour lire ou écrire les données comme d'habitude.

t + p->d0 + i*in0 + j*in1

Adresse de l'élément localisé à la ième place selon la première variable et à la jème place selon la deuxième variable.

La même technique est utilisée si le signal sur la borne a plus de deux dimensions.

5-2-4. Exemple de routine externe interfacée en C et Fortran

Description de l'algorithme

L'exemple suivant de traitement de matrice externe est fourni avec Mustig :

Voici la matrice d'entrée 3x2 sur borne 1, entrée en cliquant deux fois sur la macro Matrice/li/co :

et voici la matrice 3x2 de sortie calculée passée sur la borne 6 :

Elle a été calculée en utilisant l'algorithme suivant écrit dans la routine externe :

  1. Déclarez une valeur variable statique = 0.5
  2. Ajoutez le contenu de l'entrée scalaire sur la borne #1 à la première ligne - Ajoutez la valeur au résultat.
  3. Incrémenter la valeur par le contenu de l'entrée scalaire borne #1
  4. Répétez 2 et 3 pour les deux autres lignes de la matrice d'entrée pour obtenir la matrice de sortie

Les résultats suivants sont calculés par la routine externe et sont passés aux bornes de la sortie:

Borne 4 Deuxième colonne de la matrice de sortie calculée
Borne 5 Deuxième ligne de la matrice de sortie calculée
Borne 6 Matrice de sortie calculée
Borne 7 Somme des éléments de la matrice d'entrée

 

La routine C externe

Le code C de la routine externe est donné ci-dessous : les commentaires expliquent comment les paramètres sont retrouvés réellement.

/* Example of external << C >> routine */

/*

IMPORTANT NOTE

In this external routine, the pins are referred to using variables which contain a "pin number". These pin numbers range from 0 to the number of CONNECTED pins minus 1.

In Mustig, the Extern module numbers the pins from 1 to the number of EXISTING pins (either connected or not) and some pins are not connected.

Therefore, pin N in this code does NOT correspond to pin N as it is numbered on the interface text of the Extern Mustig module

*/

 

void __export matrice(t,p,r)

 

char *t; /* Pointer to the Mustig data table (array) */

char *r; /* String to return potential error messages */

 

struct {long /* Parameter table */

 

i, /*index initialized to "2" */

nb_pins, /*number of pins used*/

 

/*pin 0, scalar input, integer on 4 octets*/

nvar0, /* number of variables support of signal on

the pin (should be 0) */

d0, /* offset in array t */

 

/*pin 1,matrix input, real*/

nvar1, /* number of variables support of signal on

the pin (should be 2) */

d1, /* offset in array t */

in1, /* increment on the first dimension */

n1, /* number of values */

in12, /* increment on the second dimension */

n12, /* number of values */

 

/*pin 2,vector output, real*/

nvar2, /* number of variables support of signal on

the pin (should be 1) */

d2, /* offset in array t */

in2, /* increment */

n2, /* number of values */

 

/*pin 3,vector output, real*/

nvar3, /* number of variables support of signal on

the pin (should be 1) */

d3, /* offset in array t */

in3, /* increment */

n3, /* number of values */

 

/*pin 4, matrix output, real*/

nvar4, /* number of variables support of signal on

the pin (should be 2)*/

d4, /* offset in array t */

in4, /* increment on the first dimension */

n4, /* number of values */

in42, /* increment on the first dimension */

n42, /* number of values */

/*pin 5, scalar output, real*/

nvar5, /* number of variables support of signal on

the pin (should be 0) */

d5; /* offset in array t */

 

} *p;

/* End of the description of the pointer to the parameter list */

 

/* Begin the main program */

{

static float value=0.5;

int err,i,j;

float *a,*b,*a0,*b0,*v1,*v2;

long val0;

float fval0,*afval5,s;

long n1,n2,inc1,inc12,incv1,incv2,inc4,inc42;

 

/* Check the input data and declare intermediate variables */

if(p->nb_pins != 6) {strncpy(r,"wrong number of connected

pins,80);return;}

/*pin 0*/

if(p->nvar0 != 0){strncpy(r,"Connected Pin 0 not a scalar",80);return;}

val0=*((long*)(t+p->d0));

fval0=val0;

 

/*pin 1*/

if(p->nvar1 != 2){strncpy(r," Connected Pin 1 not a matrix",80);return;}

a0=(float*)(t+p->d1); /*address of input matrix*/

n1 = p->n1; /* number of matrix points along 1st dimension */

n2 = p->n12; /* number of matrix points along 2nd dimension */

inc1 = p->in1; /* increment of matrix points along 1st dim */

inc12 = p->in12; /* increment of matrix points along 2nd dim */

 

/*pin 2*/

if(p->nvar2 != 1){strncpy(r," Connected Pin 2 not a vector",80);return;}

v1=(float*)(t+p->d2); /* address of first vector output */

if(p->n2 != n1){strncpy(r,"error vector-matrix",80);return;}

incv1 = p->in2; /* increment of vector points */

 

/*pin 3*/

if(p->nvar3 != 1){strncpy(r," Connected Pin 3 not a vector",80);return;}

v2=(float*)(t+p->d3); /* address of second vector output */

if(p->n3 != n2){strncpy(r,"error vector-matrix",80);return;}

incv2 = p->in3; /* increment of vector points */

 

/*pin 4*/

if(p->nvar4 != 2){strncpy(r," Connected Pin 4 not a matrix",80);return;}

b0=(float*)(t+p->d4); /* address of output matrix */

inc4 = p->in4; /* increment of matrix points along 1st dim */

inc42 = p->in42; /* increment of matrix points along 2nd dim */

 

/*pin 5*/

if(p->nvar5 != 0){strncpy(r," Connected pin 5 not a scalar",80);return;}

afval5=(float*)(t+p->d5);

s=0;

 

/*calculation of the output matrix from the input matrix */

for(i=0;i<n1;i++){

a=a0;

b=b0;

for(j=0;j<n2;j++){

*b= *a + fval0 + value;

s += *a;

a += inc12;

b += inc42;

}

value += fval0;

a0 += inc1;

b0 += inc4;

}

*afval5=s; /*result on pin5 is the sum of the terms of the input matrix*/

/*calculation of first vector = second column of matrix b*/

b0=(float*)(t+p->d4);/*address of output matrix*/

b=b0 + inc42;

for(i=0;i<n1;i++){

*v1 = *b;

v1 += incv1;

b += inc4;

}

/*calculation of second vector = second line of matrix b*/

b=b0 + inc4;

for(i=0;i<n2;i++){

*v2 = *b;

v2 += incv2;

b += inc42;

}

}

 

Routine externe Fortran

Le code FORTRAN pour la même routine externe est donné ci-dessous :

 

c example of external routine FORTRAN

 

program MATRIX(t,p,r)

 

c systematic declarations for Mustig interface

integer*4 p

integer*1 t(0:1)

integer*1 r(80)

 

c declarations required for every declared pin

c - an address

c - for each support variable :

c - an increment

c - a number of values

c

integer*4 ad0,ad1,ad2,ad3,ad4,ad5,inc1,nv1,inc12,nv12

integer*4 inc2,nv2,inc3,nv3,inc4,nv4,inc42,nv42,ierr

external SPMATRIX

integer SPMATRIX

c a call to 'mstg0v' or 'mstg1v' or 'mstg2v'

c for each pin declared in the MUSTIG module

c pin 0

call mstg0v(p,ad0,ierr)

if(ierr .NE. 0) GOTO 100

c pin 1

call mstg2v(p,ad1,inc1,nv1,inc12,nv12,ierr)

if(ierr .NE. 0) GOTO 100

c pin 2

call mstg1v(p,ad2,inc2,nv2,ierr)

if(ierr .NE. 0) GOTO 100

c pin 3

call mstg1v(p,ad3,inc3,nv3,ierr)

if(ierr .NE. 0) GOTO 100

c pin 4

call mstg2v(p,ad4,inc4,nv4,inc42,nv42,ierr)

if(ierr .NE. 0) GOTO 100

c pin 5

call mstg0v(p,ad5,ierr)

 

c test of parameter coherency

100 if (ierr .NE. 0)then

call mstger(r,'Incoherent call')

return

endif

if(nv1 .NE. nv2) GOTO 200

if(nv12 .NE. nv3) GOTO 200

if(nv1 .NE. nv2) GOTO 200

if(nv1 .NE. nv4) GOTO 200

if(nv12 .NE. nv42) GOTO 200

GOTO 300

200 call mstger(r,'Lengths are incoherent')

c call calculation subroutine

300 ierr= SPMATRIX(t(ad0),

1 t(ad1),inc1,nv1,inc12,nv12,

2 t(ad2),inc2,

3 t(ad3),inc3,

4 t(ad4),inc4,inc42,

5 t(ad5))

c test return; error message if needed

if (ierr .NE. 0)call mstger(r,'Too large size')

end

 

c Utility subroutines : mstg0v,mstg1v,mstg2v and mstger

INCLUDE Mustig_inc.for

c calculation subroutine

integer function SPMATRIX(a0,

1 a1,inc1,li,inc12,co,

2 a2,inc2,

3 a3,inc3,

4 a4,inc4,inc42,

5 a5)

integer*4 inc1,li,inc12,co

integer*4 inc2,inc3,inc4,inc42

integer*4 a0

real*4 a1(0:1)

real*4 a2(0:1)

real*4 a3(0:1)

real*4 a4(0:1)

real*4 a5

integer*4 ada1,ada2,ada3,ada4,i0,j0

real*4 value,s,fval0

if ((li.GT.1000).OR.(co.GT.1000)) then

SPMATRIX=1

return

endif

fval0=a0

value=0.5

ada2=0

ada3=0

s=0

i0=0

j0=0

c calculation of the result matrix from the data matrix

do 10 i=1,li

ada1=i0

ada4=j0

do 20 j=1,co

a4(ada4)=a1(ada1)+value+fval0

s=s+a1(ada1)

ada1=ada1+inc12

ada4=ada4+inc42

20 continue

value=value+fval0

i0=i0+inc1

j0=j0+inc4

10 continue

a5=s

c calculation of the 1st output vector = 2nd column of the output matrix

ada4=inc42

ada1=0

do 30 i=1,li

a2(ada2)=a4(ada4)

ada2=ada2+inc2

ada4=ada4+inc4

30 continue

c calculation of the 2nd result vector = 2nd line of the output matrix

ada4=inc4

do 40 i=1,co

a3(ada3)=a4(ada4)

ada3=ada3+inc3

ada4=ada4+inc42

40 continue

SPMATRIX=0

end

5-3. Le cas spécial Macintosh

5-3-1. Macintosh 680xx

Le code externe doit être une ressource de type MUEX . Son nom doit être le même que celui entré sur la face avant du module Extern. Le fichier qui contient cette ressource peut être dans le répertoire Mustig ou dans le répertoire MUSTIG overlays .

Le code doit être self-consistent et a pu être produit par tout langage (Pascal, C,...), pourvu que des bibliothèques externes n'aient pas été utilisées. L'environnement à l'appel doit être restauré quand le traitement externe est fini.

Vous pouvez lancer la routine externe en utilisant le débogueur symbolique de THINK-C : suivez les directives dans Exemples avec externes / Debug Mustig / Doc Debug.

Cas spécial Fortran

Vous pouvez interfacer des routines Fortran avec MUSTIG en utilisant l'environnement FORTRAN ABSOFT 020 et le module Mustig Fortran. Ce dernier est utilisé exactement de la même manière que le module Extern . Voir la routine Externe Fortran pour un exemple d'interface du point de vue du code. Aussi voir les exemples Somme et Tracer dans le répertoire MUSTIG overlays .

Vous pouvez utiliser le débogueur symbolique Absoft Fortran : suivez les directives dans Exemples avec externes / Debug Mustig / Doc Debug.

La différence entre utiliser le module Fortran et utiliser le module Extern est la suivante :

5-3-2. Power Macintosh

Vous pouvez construire des DLL d'entrées multiples. Voir l'exemple de la matrice et le projet C associé.

5-4. Cas spécial UNIX

La structure des routines est semblable à celle décrite dans les sections antérieures. Cependant, deux modes de chargement sont disponibles :

5-4-1. Le processus de mémoire partagée

Note : Ce mode de chargement démodé a été conservé pour assurer la compatibilité totale avec les programmes développés en utilisant des versions antérieures de Mustig. Cependant, le mode de chargement dynamique est recommandé.

Le principe

Ce mode exige qu'un grand segment de mémoire partagée soit créé pour que MUSTIG puisse y construire son tableau de données. Par conséquent, assurez-vous que la configuration de votre système autorise à créer des segments de dimension suffisante dans la mémoire partagée. La dimension par défaut est 4MOctets, d'autres valeurs peuvent être entrées dans Edition / Options.

Les modules Extern et Fortran sont équivalents dans ce mode.

Ce mode est mis en cliquant sur Externes en mémoire partagée dans Edition/Options.

Exemples

Le point d'entrée doit être nommé main_ext :

subroutine main_ext(t,p,r)

integer*4 p

integer*1 t(0:1)

integer*1 r(80)

.

.

main_ext(t,p,r)

char *t;

char *r;

struct {long

i,

nb_bornes,

nvar1,

d1,

nvar2,

d2,

in2,

n2;

} *p;

.

.

Compiler la routine externe

Les routines doivent être linkées à un sous programme délivré avec Mustig :

main_ext_f.o pour les routines du FORTRAN

main_ext_c.o pour les routines C

Des exemples de commandes du link sont:

cc -o My_routine main_ext_c.o My_Routine.c

cc -o My_routine main_ext_f.o My_Routine.f

My_Routine est la routine externe créée : son nom doit être entré dans MUSTIG sur la face avant du module Extern ou Fortran.

Note : Si une erreur se produit, ce peut être nécessaire de nettoyer les segments en utilisant les commandes UNIX ipcs et ipcrm.

Sur quelques machines, le nombre de fois qu'une routine peut être appelée est limité à 16384.

5-4-2. Le processus de chargement dynamique

Ce mode est choisi en ne cochant pas l'option Externes en mémoire artagée dans Edition/Options. Il n'exige pas qu'un grand segment de mémoire partagée soit créé. Pour permettre à la routine externe d'être gérée par le système du Lien Dynamique, il y a deux différences par rapport au processus de mémoire partagée :

My_Routine(t,p,r)

char *t;

char *r;

struct { long

i,

.

.

Cette routine peut être incluse dans un fichier source My_Routine.c . Dans ce cas, la routine My_Routine.dll compilée sera recherchée et utilisée par MUSTIG.