Novembre 2024 | Lun | Mar | Mer | Jeu | Ven | Sam | Dim |
---|
| | | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | | Calendrier |
|
|
| Structure des variables en Panoramic | |
| | Auteur | Message |
---|
Jack Admin
Nombre de messages : 2394 Date d'inscription : 28/05/2007
| Sujet: Structure des variables en Panoramic Jeu 21 Mar 2019 - 11:26 | |
| Klaus, qui est en train de développer des opérations sur les matrices dans sa DLL a besoin de connaître comment sont structurées les variables indicées dans Panoramic. A ce sujet, il m'a envoyé des MP, mais je vais lui répondre sur le forum, parce que d'autres personnes sont peut-être intéressés. Une fois n'est pas coutume, je vais "dévoiler" une partie du code source de Panoramic, en Delphi, car Panoramic est codé en Delphi. Je pense que les commentaires dans le source sont assez explicites. Déclaration des variables: - Code:
-
type // mémorisation des variables simples et indicées Tableau_Variables = record // NOM Var_Nom : string;
// TYPE Var_Typ : integer; // 1=entier, 2=chaine, 3=réel, // 4=entier à 1 indice, 5=chaine à 1 indice, 6=réel à 1 indice // 7=entier à 2 indices, 8=chaine à 2 indices, 9=réel à 2 indices // 10=entier à 3 indices, 11=chaine à 3 indices, 12=réel à 3 indices
// PORTEE Var_Rng : string; // réserve, non utilisé
// VALEUR pour les variables SIMPLES Var_Int : integer; // valeur si type 1(=entier) Var_Str : string; // valeur si type 2(=string) Var_Rel : real; // valeur si type 3(=réel)
// ADRESSE du premier élément dans les tableaux TI, TR, TC, TI2, TC2, TR2, TI3, TC3, TR3 pour les variables INDICEES Tab_Var_Int : integer; // adresse du premier élément dans TI si type=4, ou dans TI2 si type=7, ou dans TI3 si type=10 Tab_Var_Str : integer; // adresse du premier élément dans TR si type=5, ou dans TR2 si type=8, ou dans TR3 si type=11 Tab_Var_Rel : integer; // adresse du premier élément dans TC si type=6, ou dans TC2 si type=9, ou dans TC3 si type=12 Tab_Var_Int2 : integer; // adresse du deuxième élément dans TI2 si type=7 Tab_Var_Str2 : integer; // adresse du deuxième élément dans TR2 si type=8 Tab_Var_Rel2 : integer; // adresse du deuxième élément dans TC2 si type=9 Tab_Var_Int3 : integer; // adresse du troisième élément dans TI3 si type=10 Tab_Var_Str3 : integer; // adresse du troisième élément dans TR3 si type=11 Tab_Var_Rel3 : integer; // adresse du troisième élément dans TC3 si type=12
// DIMENSION des indices Tab_Max_Int : integer; // taille (indice1 max) si entier indicé (type 4) Tab_Max_Str : integer; // taille (indice1 max) si chaîne indicé (type 5) Tab_Max_Rel : integer; // taille (indice1 max) si réel indicé (type 6) Tab_Max_Int2 : integer; // taille (indice2 max) si entier indicé (type 7) Tab_Max_Str2 : integer; // taille (indice2 max) si chaîne indicé (type Tab_Max_Rel2 : integer; // taille (indice2 max) si réel indicé (type 9) Tab_Max_Int3 : integer; // taille (indice3 max) si entier indicé (type 10) Tab_Max_Str3 : integer; // taille (indice3 max) si chaîne indicé (type 11) Tab_Max_Rel3 : integer; // taille (indice3 max) si réel indicé (type 12) end;
var tv : Array of Tableau_Variables; // tableau des variables avec le nom, le type, la valeur
ti : Array of integer; // valeurs des variables indicées de type 4 tr : Array of real; // valeurs des variables indicées de type 5 tc : Array of string; // valeurs des variables indicées de type 6 ti2 : Array of Array of integer; // valeurs des variables indicées de type 7 tr2 : Array of Array of real; // valeurs des variables indicées de type 8 tc2 : Array of Array of string; // valeurs des variables indicées de type 9 ti3 : Array of Array of Array of integer; // valeurs des variables indicées de type 10 tr3 : Array of Array of Array of real; // valeurs des variables indicées de type 11 tc3 : Array of Array of Array of string; // valeurs des variables indicées de type 12 Code d'affectation de valeur dans une variable: - Code:
-
// ----------------------------------------------------------------------------- procedure Affecte_Variable_Int(Position : integer; Valeur : integer); // ========== // 12-09-2005 // ========== // affecte une variable simple entière dans le tableau des variables TV : VALEUR est mis dans le rang POSITION begin
DNoyau.tv[Position].Var_Int := Valeur; // valeur par défaut
//ShowMessage('affecte valeur '+FloatToStr(Valeur)+' en position '+IntToStr(Position)); end; // ----------------------------------------------------------------------------- procedure Affecte_Variable_Str(Position : integer; Valeur : string); // ========== // 12-09-2005 // ========== // affecte une variable simple chaine dans le tableau des variables TV : VALEUR est mis dans le rang POSITION begin
DNoyau.tv[Position].Var_Str := Valeur; // valeur par défaut
//ShowMessage('affecte valeur chaine->'+Valeur+' en position '+IntToStr(Position)); end; // ----------------------------------------------------------------------------- procedure Affecte_Variable_Rel(Position : integer; Valeur : real); // ========== // 12-09-2005 // ========== // affecte une variable simple réelle dans le tableau des variables TV : VALEUR est mis dans le rang POSITION begin
DNoyau.tv[Position].Var_Rel := Valeur; // valeur par défaut
//ShowMessage('affecte valeur '+FloatToStr(Valeur)+' en position '+IntToStr(Position)); end; // ----------------------------------------------------------------------------- procedure Affecte_Variable_Tabl_Int(Position , Indice , Valeur : integer); // ========== // 13-12-2010 // ========== // affecte VALEUR dans la variable indicée entière dans les tableaux TV et TI // la variable indicée est supposée exister dans TV // et l'indice est supposé être inférieur à la taille maximale
// POSITION = rang de la variable dans le tableau de variables TV // INDICE = indice de la variable // VALEUR = valeur à mettre dans variable(INDICE)
begin // dans TV, on a la position du premier élément dans le tableau TI // tv[Nbre_Var].Tab_Var_Int = adresse de l'élément 0
ti[ DNoyau.tv[Position].Tab_Var_Int + Indice ] := Valeur;
//ShowMessage('affecte valeur tableau entier : '+ IntToStr(Valeur) + ' mis en TI['+IntToStr(DNoyau.tv[Position].Tab_Var_Int + Indice) + ']');
end; // ----------------------------------------------------------------------------- procedure Affecte_Variable_Tabl_Str(Position , Indice : integer; Valeur : string); // ========== // 13-12-2010 // ========== // affecte VALEUR dans la variable indicée chaine dans les tableaux TV et TC // la variable indicée est supposée exister dans TV // et l'indice est supposé être inférieur à la taille maximale
// POSITION = rang de la variable dans le tableau de variables TV // INDICE = indice de la variable // VALEUR = valeur à mettre dans variable(INDICE)
begin // dans TV, on a la position du premier élément dans le tableau TS // tv[Nbre_Var].Tab_Var_Str = adresse de l'élément 0
tc[ DNoyau.tv[Position].Tab_Var_Str + Indice ] := Valeur; end; // ----------------------------------------------------------------------------- procedure Affecte_Variable_Tabl_Rel(Position , Indice : integer; Valeur : real); // ========== // 13-12-2010 // ========== // affecte VALEUR dans la variable indicée réelle dans les tableaux TV et TR // la variable indicée est supposée exister dans TV // et l'indice est supposé être inférieur à la taille maximale
// POSITION = rang de la variable dans le tableau de variables TV // INDICE = indice de la variable // VALEUR = valeur à mettre dans variable(INDICE)
begin // dans TV, on a la position du premier élément dans le tableau TR // tv[Nbre_Var].Tab_Var_Int = adresse de l'élément 0
tr[ DNoyau.tv[Position].Tab_Var_Rel + Indice ] := Valeur; end; // ----------------------------------------------------------------------------- procedure Affecte_Variable_Tabl2_Int(Position , Indice1 , Indice2 : integer; Valeur : integer); // ========== // 13-12-2010 // ========== // affecte VALEUR dans VARIABLE(INDICE1,INDICE2) entière dans les tableaux TV et TI2 // la variable indicée est supposée exister dans TV // et les indices sont supposés être inférieurs à la taille maximale
// POSITION = rang de la variable dans le tableau de variables TV // INDICE1, INDICE2 = indices de la variable // VALEUR = valeur à mettre dans VARIABLE(INDICE1,INDICE2) dans TI2
begin // dans TV, on a la position des premiers indices dans le tableau TI2 // tv[Nbre_Var].Tab_Var_Int = adresse de l'indice1 (élément 0) // tv[Nbre_Var].Tab_Var_Int2 = adresse de l'indice2 (élément 0)
ti2[ DNoyau.tv[Position].Tab_Var_Int + Indice1 , DNoyau.tv[Position].Tab_Var_Int2 + Indice2 ] := Valeur;
//ShowMessage('affecte valeur tableau entier à 2 indices: '+ IntToStr(Valeur) + ' mis en TI2['+IntToStr(DNoyau.tv[Position].Tab_Var_Int + Indice1) // + ',' + IntToStr(DNoyau.tv[Position].Tab_Var_Int2 + Indice2) + ']');
end; // ----------------------------------------------------------------------------- procedure Affecte_Variable_Tabl2_Str(Position , Indice1 , Indice2 : integer; Valeur : string); // ========== // 13-12-2010 // ========== // affecte VALEUR dans VARIABLE(INDICE1,INDICE2) chaine dans les tableaux TV et TC2 // la variable indicée est supposée exister dans TV // et les indices sont supposés être inférieurs à la taille maximale
// POSITION = rang de la variable dans le tableau de variables TV // INDICE1, INDICE2 = indices de la variable // VALEUR = valeur à mettre dans VARIABLE(INDICE1,INDICE2) dans TC2
begin // dans TV, on a la position des premiers indices dans le tableau TC2 // tv[Nbre_Var].Tab_Var_Str = adresse de l'indice1 (élément 0) // tv[Nbre_Var].Tab_Var_Str2 = adresse de l'indice2 (élément 0)
tc2[ DNoyau.tv[Position].Tab_Var_Str + Indice1 , DNoyau.tv[Position].Tab_Var_Str2 + Indice2 ] := Valeur; end; // ----------------------------------------------------------------------------- procedure Affecte_Variable_Tabl2_Rel(Position , Indice1 , Indice2 : integer; Valeur : real); // ========== // 13-12-2010 // ========== // affecte VALEUR dans VARIABLE(INDICE1,INDICE2) réelle dans les tableaux TV et TR2 // la variable indicée est supposée exister dans TV // et les indices sont supposés être inférieurs à la taille maximale
// POSITION = rang de la variable dans le tableau de variables TV // INDICE1, INDICE2 = indices de la variable // VALEUR = valeur à mettre dans VARIABLE(INDICE1,INDICE2) dans TR2
begin // dans TV, on a la position des premiers indices dans le tableau TR2 // tv[Nbre_Var].Tab_Var_Rel = adresse de l'indice1 (élément 0) // tv[Nbre_Var].Tab_Var_Rel2 = adresse de l'indice2 (élément 0)
tr2[ DNoyau.tv[Position].Tab_Var_Rel + Indice1 , DNoyau.tv[Position].Tab_Var_Rel2 + Indice2 ] := Valeur; end; // ----------------------------------------------------------------------------- procedure Affecte_Variable_Tabl3_Int(Position , Indice1 , Indice2 , Indice3 : integer; Valeur : integer); // ========== // 12-02-2018 // ========== // affecte VALEUR dans VARIABLE(INDICE1,INDICE2,INDICE3) entière dans les tableaux TV et TI3 // la variable indicée est supposée exister dans TV // et les indices sont supposés être inférieurs à la taille maximale
// POSITION = rang de la variable dans le tableau de variables TV // INDICE1, INDICE2, INDICE3 = indices de la variable // VALEUR = valeur à mettre dans VARIABLE(INDICE1,INDICE2, INDICE3) dans TI3
begin // dans TV, on a la position des premiers indices dans le tableau TI3 // tv[Nbre_Var].Tab_Var_Int = adresse de l'indice1 (élément 0) // tv[Nbre_Var].Tab_Var_Int2 = adresse de l'indice2 (élément 0) // tv[Nbre_Var].Tab_Var_Int3 = adresse de l'indice3 (élément 0)
ti3[ DNoyau.tv[Position].Tab_Var_Int + Indice1 , DNoyau.tv[Position].Tab_Var_Int2 + Indice2 , DNoyau.tv[Position].Tab_Var_Int3 + Indice3] := Valeur;
//ShowMessage('affecte valeur tableau entier à 3 indices: '+ IntToStr(Valeur) + ' mis en TI3['+IntToStr(DNoyau.tv[Position].Tab_Var_Int + Indice1) // + ',' + IntToStr(DNoyau.tv[Position].Tab_Var_Int2 + Indice2) // + ',' + IntToStr(DNoyau.tv[Position].Tab_Var_Int3 + Indice3) + ']');
end; // ----------------------------------------------------------------------------- procedure Affecte_Variable_Tabl3_Str(Position , Indice1 , Indice2 , Indice3 : integer; Valeur : string); // ========== // 12-02-2018 // ========== // affecte VALEUR dans VARIABLE(INDICE1,INDICE2,INDICE3) chaine dans les tableaux TV et TC3 // la variable indicée est supposée exister dans TV // et les indices sont supposés être inférieurs à la taille maximale
// POSITION = rang de la variable dans le tableau de variables TV // INDICE1, INDICE2, INDICE3 = indices de la variable // VALEUR = valeur à mettre dans VARIABLE(INDICE1,INDICE2, INDICE3) dans TC3
begin // dans TV, on a la position des premiers indices dans le tableau TC3 // tv[Nbre_Var].Tab_Var_Str = adresse de l'indice1 (élément 0) // tv[Nbre_Var].Tab_Var_Str2 = adresse de l'indice2 (élément 0) // tv[Nbre_Var].Tab_Var_Str3 = adresse de l'indice3 (élément 0)
tc3[ DNoyau.tv[Position].Tab_Var_Str + Indice1 , DNoyau.tv[Position].Tab_Var_Str2 + Indice2 , DNoyau.tv[Position].Tab_Var_Str3 + Indice3] := Valeur; end; // ----------------------------------------------------------------------------- procedure Affecte_Variable_Tabl3_Rel(Position , Indice1 , Indice2 , Indice3 : integer; Valeur : real); // ========== // 12-02-2018 // ========== // affecte VALEUR dans VARIABLE(INDICE1,INDICE2,INDICE3) réelle dans les tableaux TV et TR3 // la variable indicée est supposée exister dans TV // et les indices sont supposés être inférieurs à la taille maximale
// POSITION = rang de la variable dans le tableau de variables TV // INDICE1, INDICE2, INDICE3 = indices de la variable // VALEUR = valeur à mettre dans VARIABLE(INDICE1,INDICE2, INDICE3) dans TR3
begin // dans TV, on a la position des premiers indices dans le tableau TR3 // tv[Nbre_Var].Tab_Var_Rel = adresse de l'indice1 (élément 0) // tv[Nbre_Var].Tab_Var_Rel2 = adresse de l'indice2 (élément 0) // tv[Nbre_Var].Tab_Var_Rel3 = adresse de l'indice3 (élément 0)
tr3[ DNoyau.tv[Position].Tab_Var_Rel + Indice1 , DNoyau.tv[Position].Tab_Var_Rel2 + Indice2 , DNoyau.tv[Position].Tab_Var_Rel3 + Indice3] := Valeur; end; _________________ username : panoramic@jack-panoramic password : panoramic123 | |
| | | Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
| Sujet: Re: Structure des variables en Panoramic Jeu 21 Mar 2019 - 11:52 | |
| Merci beaucoup, Jack ! Je vais étudier cela avec attention. Un premier coup d'oeil rapide confirme que j'avais bien repéré la structure de la table de des variables pour des variables simples ou indicées avec 1 ou deux dimensions. L'extension à 3 dimensions est logique. Je constate également que tous les tableaux sont des arrays dynamiques. Cela met un peu à mal ma technique de détermination et mémorisation des adresses du premier élément de chaque variable, car cela peut bouger selon les DIMs effectués dynamiquement. Ce n'est pas une grosse surprise - je m'y attendais un peu. Après tout, à tout moment, on peut définir une nouvelle variable ou en supprimer une, ce qui change évidemment toutes les adresses. Je vais donc revoir mon codage dans ce sens. A l'heure actuelle, je suis en mesure de déterminer le type d'une variable, sa ou ses dimensions et la ou les adresses des premiers éléments dans chaque dimension, juste avec un appel de ce genre: - Code:
-
MA1% = dll_call2("CreateMatrix",adr(nom$),adr(valeurs%)) J'ai créé un objet TPMatrix défini comme classe directement, avec ses paramètres privées et ses méthodes. Je vais faire de sorte que les variables et pointeurs internes se mettent à jour automatiquement, en fonction de la configuration dynamique des différents tableaux de Panoramic. A ce jour, j'ai une version complètement opérationnelle dans un contexte sans création ou suppression de variables, après la création de mes objets TPMatrix. C'est donc à ce niveau que je dois approfondir. Un grand MERCI, Jack ! | |
| | | Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
| Sujet: Re: Structure des variables en Panoramic Lun 25 Mar 2019 - 11:47 | |
| Voilà où j'en suis, Jack:
J'ai découvert que l'ensemble des tableaux que tu as généreusement documentés dans ton message ci-dessus, sont des "arrays dynamiques". En tant que tels, leurs tailles varient au fil des commandes DIM, DIM_LOCAL et FREE ce qui est normal.
Ce qui est beaucoup plus gênant, c'est que leur emplacement en mémoire virtuelle change également. En effet, lors d'un agrandissement d'un array dynamique, celui-ci est recopié en son intégralité vers un novel endroit, avec le supplément d'espace requis. Pire - ceci se passe tableau par tableau, et ainsi, on ne peut même plus être sûr de la suite physique des tableaux en mémoire.
J'ai dû créer une fonction qui localise dynamiquement la table de symboles (tv ) car elle aussi bouge. Puis une autre pour retrouver les pointeurs des premiers éléments de chaque ligne d'un tableau de deux dimensions, à partir de l'adresse adr(tableau) passée par Panoramic.
Question: Est-ce qu'il y a un endroit "fixe" donnant des pointeurs sur tous ces tableaux ? Si tel était le cas, le problème était résolu et je pourrais facilement actualiser mes pointeurs sans recourir à une fonction externe pour repréciser adr(tableau) pour chaque tableau concerné. | |
| | | Jack Admin
Nombre de messages : 2394 Date d'inscription : 28/05/2007
| Sujet: Re: Structure des variables en Panoramic Mer 27 Mar 2019 - 19:43 | |
| Malheureusement, il n'y a pas de pointeurs sur les tableaux dynamiques qui contiennent les valeurs des variables. _________________ username : panoramic@jack-panoramic password : panoramic123 | |
| | | Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
| Sujet: Re: Structure des variables en Panoramic Mer 27 Mar 2019 - 21:02 | |
| Merci, Jack. Je continuerai donc avec la solution que je me suis fixée. Cependant, j'ai jait une découverte, pour DELPHI 6 tout au moins. Lors de mes multiples essais, j'ai créé un array dynamique de 1 dimension, puis un autre de deux dimensions. Et j'ai analysé ce qui se passe lorsqu'un inspecte le contenu de l'adresse de ces arrays. Et c'est intéressant: - Code:
-
var ar1dim: array of integer; ar2dim: array of array of integer; ...
Alors, @ar1dim pointe sur un mot qui contient l'adresse de la variable ar1dim. Idem pour ar2dim. La valeur de @ar1dim et @ar2dim ne change jamais, ce qui veut dire que ce mot de 32 bits n'est pas sur le heap et n'est pas déplacé. Par contre, le contenu @ar1dim^ change et pointe chaque fois sur la vraie variable. A cette adresse, on trouve quelques codes dont je n'ai pas encore déchiffré le sens, puis un mot contenant un pointeur vers les données ar1dim[0] ou ar2dim[0,0], et les données de cette ligne se suivent, dans interruption. Dans le cas de ar2dim, après le pointeur mentionné ci-dessus, il y en a un second qui pointe vers ar2dim[1,0], et ainsi de suite. Revenant aux tables de Panoramic dont nous parlons, je suis sûr d'une chose: il y a quelque part un pointeur vers les variables vt et les autres, et ce pointeur est à une adresse fixe. Le tout c'est d'arriver à le localiser. J'ai trouvé une solution permettant d'avoir les adresses des données sans passer par ce système de pointeurs, mais c'est lourd à mettre en oeuvre côté programmeur Panoramic, et donc potentiellement source d'erreur. Je continuerai donc de chercher un moyen de localiser ces pointeurs qui contiendrait les valeurs de @vt etc. Car, après tout, cela ne peut pas être totalement fluctuant. Delphi a forcément besoin d'un repère pour localiser l'ancien tableau pour pouvoir le recopier vers un nouveau en cas de SetLength avec des dimensions plus grandes, et pour pouvoir accéder en temps réel aux données alors que le compilateur de peut pas savoir où elles sont. Et la donc Delphi le dit bien: l'emploi d'un array dynamique "ajoute un niveau d'indirection". Il y a donc forcément un endroit fixe avec un pointeur vers la définition dynamique. Oui, je sais... je suis têtu. Mais en informatique, ce n'est que comme ça qu'on y arrive ! | |
| | | Contenu sponsorisé
| Sujet: Re: Structure des variables en Panoramic | |
| |
| | | | Structure des variables en Panoramic | |
|
Sujets similaires | |
|
| Permission de ce forum: | Vous ne pouvez pas répondre aux sujets dans ce forum
| |
| |
| |