FORUM DE DISCUSSION SUR LE LANGAGE PANORAMIC

Développement d'applications avec le langage Panoramic
 
AccueilAccueil  FAQFAQ  RechercherRechercher  S'enregistrerS'enregistrer  MembresMembres  GroupesGroupes  Connexion  
Derniers sujets
» Traceur de courbes représentatives des fonctions y = f(x)
par Jean Claude Aujourd'hui à 9:45

» Problème de syntaxe
par Klaus Hier à 12:40

» KGF_dll - nouvelles versions
par Klaus Hier à 12:36

» Compilateur FBPano
par jean_debord Hier à 12:31

» Toolbar en Panoramic
par ygeronimi Dim 22 Jan 2017 - 23:56

» Documentation des évènements
par Klaus Dim 22 Jan 2017 - 16:46

» Klaus est de retour!
par jjn4 Dim 22 Jan 2017 - 16:31

» Texte sur image
par Jicehel Dim 22 Jan 2017 - 12:23

» MIN - MAX avec SPIN
par ygeronimi Sam 21 Jan 2017 - 10:02

» HEIGHT_CLIENT(N)
par ygeronimi Ven 20 Jan 2017 - 16:41

» Non demande de commande
par ygeronimi Jeu 19 Jan 2017 - 11:50

» Bataille navale sous-marine
par papydall Jeu 19 Jan 2017 - 2:19

» Version instantanée du 16/01/2017 : PANORAMIC V 0.9.27i10
par mindstorm Mer 18 Jan 2017 - 21:05

» PLM N34
par Froggy One Mer 18 Jan 2017 - 17:32

» saving 1.png [RÉSOLU]
par Froggy One Mar 17 Jan 2017 - 19:44

Navigation
 Portail
 Index
 Membres
 Profil
 FAQ
 Rechercher
Rechercher
 
 

Résultats par :
 
Rechercher Recherche avancée
Janvier 2017
LunMarMerJeuVenSamDim
      1
2345678
9101112131415
16171819202122
23242526272829
3031     
CalendrierCalendrier

Partagez | 
 

 Adresses dans un tableau à 2 dimensions

Voir le sujet précédent Voir le sujet suivant Aller en bas 
AuteurMessage
Klaus



Nombre de messages : 9436
Age : 67
Localisation : Ile de France
Date d'inscription : 29/12/2009

MessageSujet: Adresses dans un tableau à 2 dimensions   Dim 13 Nov 2016 - 5:30

A ce jour, pour un tableau en Panoramic, on peut utiliser la fonction ADR() .

Pour un tableau d'une seule dimension, elle retourne l'adresse de la case (0), et toutes les autres cases occupent les cellules juste à la suite.

Pour un tableau de deux dimensions, elle retourne l'adresse de la case (0,0), et les adresses (1,0), ... jusqu'à (n,0) se trouvent juste à la suite. Mais l'adresse de la cellule (1,0) ? Et (2,0) et ainsi de suite ? Mystère.

J'avais fait une suggestion de nouvelle fonction solvant ce problème, et je verrai bien si Jack a le temps et l'envie de faire quelque chose dans ce domaine. En attendant, j'ai trouvé une astuce, avec l'aide de KGF.dll, pour contourner ce manque. Je peux trouver les adresses de ces cellules (et donc accéder au "vecteur" concernant chaque valeur du premier indice), pour un tableau d'entiers. Pour les flottants et les chaînes de caractères ma méthode pourra être étendue également.

En voici une démo:
Code:
' trouver_les_series_pour_un_tableau_de_entiers.bas
dim debug% : debug% = 0
dim i%, j%, k%, a$, res%
width 0,1200 : height 0,600
dll_on "KGF.dll"
memo 2 : left 2,                 10 : width 2,200 : height 2,500 : bar_vertical 2
memo 3 : left 3,left(2)+width(2)+10 : width 3,400 : height 3,500 : bar_vertical 3 : if debug%=0 then hide 3
memo 4 : left 4,left(3)+width(3)+10 : width 4,300 : height 4,500 : bar_vertical 4 : if debug%=0 then hide 4


res% = dll_call1("LocalizePanoramicSymbolTable",adr(number_click))

' définition d'un premier tableau
dim test%(4,5) : ' , test1%(3,4)

' définition du deuxième tableau
dim buf%(4,2100)

' définition d'un troisième tableau
dim essai%(4,4)


tester(1)
tester(2)
tester(3)

end

sub tester(cas%)
  dim_local a%(5), res%, n%, s$

for n%=0 to 4
 select cas%
   case 1
     s$ = "test%("+str$(n%)+",0)"
     test%(n%,0)  = hex("FF77CC00")+1
     test%(n%,1)  = hex("FF77CC00")+2
     a%(n%) = dll_call4("FindValueInVirtualMemory",0,0,test%(n%,0),test%(n%,0))
     res% = dll_call3("DumpPanoramic",handle(4),a%(n%)-40,40) : ' dump de cette section
     item_add 3, "FindValueInVirtualMemory: adr("+s$+")="+right$("0000000"+hex$(a%(n%)),8)
     item_add 3,"adr("+s$+"="+hex$(a%(n%))+"  entête="+hex$(a%(n%)-40)
     item_add 4,"================================"
     test%(n%,0)  = 0
     test%(n%,1)  = 0
   case 2
     s$ = "buf%("+str$(n%)+",0)"
     buf%(n%,0)   = hex("FF77CC00")+1
     buf%(n%,1)   = hex("FF77CC00")+2
     a%(n%) = dll_call4("FindValueInVirtualMemory",0,0,buf%(n%,0),buf%(n%,0))
     res% = dll_call3("DumpPanoramic",handle(4),a%(n%)-40,40) : ' dump de cette section
     item_add 3, "FindValueInVirtualMemory: adr("+s$+")="+right$("0000000"+hex$(a%(n%)),8)
     item_add 3,"adr("+s$+"="+hex$(a%(n%))+"  entête="+hex$(a%(n%)-40)
     item_add 4,"================================"
     buf%(n%,0)   = 0
     buf%(n%,1)   = 0
   case 3
     s$ = "essai%("+str$(n%)+",0)"
     essai%(n%,0) = hex("FF77CC00")+1
     essai%(n%,1) = hex("FF77CC00")+2
     a%(n%) = dll_call4("FindValueInVirtualMemory",0,0,essai%(n%,0),essai%(n%,0))
     res% = dll_call3("DumpPanoramic",handle(4),a%(n%)-40,40) : ' dump de cette section
     item_add 3, "FindValueInVirtualMemory: adr("+s$+")="+right$("0000000"+hex$(a%(n%)),8)
     item_add 3,"adr("+s$+"="+hex$(a%(n%))+"  entête="+hex$(a%(n%)-40)
     item_add 4,"================================"
     essai%(n%,0) = 0
     essai%(n%,1) = 0
 end_select
next n%

 select cas%
   case 1
     item_add 2,"dim test%(4,5)"
   case 2
     item_add 2,"dim buf%(4,2100)"
   case 3
     item_add 2,"dim essai%(4,4)"
 end_select

if debug%<>0
 item_add 2,"a2-a1="+right$("0000000"+hex$(a%(1)-a%(0)),8)+"="+str$(a%(1)-a%(0))
 item_add 2,"a3-a2="+right$("0000000"+hex$(a%(2)-a%(1)),8)+"="+str$(a%(2)-a%(1))
 item_add 2,"a4-a3="+right$("0000000"+hex$(a%(3)-a%(2)),8)+"="+str$(a%(3)-a%(2))
 item_add 2,"a5-a4="+right$("0000000"+hex$(a%(4)-a%(3)),8)+"="+str$(a%(4)-a%(3))
 item_add 2,"--------------------------------"
end_if

for n%=0 to 4
  item_add 2,"adr indice "+str$(n%)+"="+hex$(a%(n%))
next n%
item_add 2,"========================"
item_add 3,"========================"
item_add 4,""
item_add 4,""
item_add 4,""
end_sub

Ce programme définit 3 tableaux, et trouve les adresses des cellules (n,0) pour chaque valeur de n.

Mais, ce que je n'ai pas encore trouvé, c'est l'endroit où est mémorisé la liste ce ces adresses, pour chaque tableau...

L'idéal serait évidemment que Jack implémente la fonction ADR_ARRAY().
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://klauspanoramic.comxa.com/index.html
Klaus



Nombre de messages : 9436
Age : 67
Localisation : Ile de France
Date d'inscription : 29/12/2009

MessageSujet: Re: Adresses dans un tableau à 2 dimensions   Mer 16 Nov 2016 - 2:19

Après une série d'essais, j'ai la conviction d'avoir trouvé une méthode pour localiser l'adresse du début des séries de cellules pour un tableau d'entiers (extensible aux tableaux de flottants et de chaînes de caractères, bien sûr). Mon petit ptogramme de démo a été étendu pour copier dans 5 fichiers binaires de 2101 mots de 32 bits (indices 0 à 2100) des 5 séries du tableau buf%(4,2100):
Code:
' trouver_les_series_pour_un_tableau_de_entiers.bas
dim debug% : debug% = 0              : ' 1=afficher des informations techniques
dim SaveArray% : SaveArray% = 1      : ' 1=écrire les séries de buf% dans des fichiers
dim i%, j%, k%, a$, res%
width 0,1200 : height 0,600
dll_on "KGF.dll"
memo 2 : left 2,                 10 : width 2,200 : height 2,500 : bar_vertical 2
memo 3 : left 3,left(2)+width(2)+10 : width 3,400 : height 3,500 : bar_vertical 3 : if debug%=0 then hide 3
memo 4 : left 4,left(3)+width(3)+10 : width 4,300 : height 4,500 : bar_vertical 4 : if debug%=0 then hide 4


res% = dll_call1("LocalizePanoramicSymbolTable",adr(number_click))

' définition d'un premier tableau
dim test%(4,5) : ' , test1%(3,4)

' définition du deuxième tableau
dim buf%(4,2100)

' définition d'un troisième tableau
dim essai%(4,4)


tester(1)
tester(2)
tester(3)

end

sub tester(cas%)
  dim_local a%(6), res%, n%, s$, ID%, i%, f$

for n%=0 to 4
 select cas%
   case 1
     s$ = "test%("+str$(n%)+",0)"
     test%(n%,0)  = hex("FF77CC00")+1
     test%(n%,1)  = hex("FF77CC00")+2
     a%(n%) = dll_call4("FindValueInVirtualMemory",0,0,test%(n%,0),test%(n%,0))
     res% = dll_call3("DumpPanoramic",handle(4),a%(n%)-40,40) : ' dump de cette section
     item_add 3, "FindValueInVirtualMemory: adr("+s$+")="+right$("0000000"+hex$(a%(n%)),8)
     item_add 3,"adr("+s$+"="+hex$(a%(n%))+"  entête="+hex$(a%(n%)-40)
     item_add 4,"================================"
     test%(n%,0)  = 0
     test%(n%,1)  = 0
   case 2
     s$ = "buf%("+str$(n%)+",0)"
     buf%(n%,0)   = hex("FF77CC00")+1
     buf%(n%,1)   = hex("FF77CC00")+2
     a%(n%) = dll_call4("FindValueInVirtualMemory",0,0,buf%(n%,0),buf%(n%,0))
     res% = dll_call3("DumpPanoramic",handle(4),a%(n%)-40,40) : ' dump de cette section
     item_add 3, "FindValueInVirtualMemory: adr("+s$+")="+right$("0000000"+hex$(a%(n%)),8)
     item_add 3,"adr("+s$+"="+hex$(a%(n%))+"  entête="+hex$(a%(n%)-40)
     item_add 4,"================================"
     if SaveArray%=1
       for i%=2 to 2100
         buf%(n%,i%) = hex("FF000000") + n%*hex("10000") + i%
       next i%
       f$ = "IntegerArray_4_2100_"+str$(n%)+".dat"
       if file_exists(f$)=1 then file_delete f$
       ID% = dll_call2("ConnectToBinaryFile",adr(f$),2)
       res% = dll_call4("WriteFileFromIntegerArray32",ID%,a%(n%),0,2100)
       res% = dll_call1("DisconnectFromBinaryFile",ID%)
     end_if
     buf%(n%,0)   = 0
     buf%(n%,1)   = 0
   case 3
     s$ = "essai%("+str$(n%)+",0)"
     essai%(n%,0) = hex("FF77CC00")+1
     essai%(n%,1) = hex("FF77CC00")+2
     a%(n%) = dll_call4("FindValueInVirtualMemory",0,0,essai%(n%,0),essai%(n%,0))
     res% = dll_call3("DumpPanoramic",handle(4),a%(n%)-40,40) : ' dump de cette section
     item_add 3, "FindValueInVirtualMemory: adr("+s$+")="+right$("0000000"+hex$(a%(n%)),8)
     item_add 3,"adr("+s$+"="+hex$(a%(n%))+"  entête="+hex$(a%(n%)-40)
     item_add 4,"================================"
     essai%(n%,0) = 0
     essai%(n%,1) = 0
 end_select
next n%

 select cas%
   case 1
     item_add 2,"dim test%(4,5)"
   case 2
     item_add 2,"dim buf%(4,2100)"
   case 3
     item_add 2,"dim essai%(4,4)"
 end_select

if debug%<>0
 item_add 2,"a2-a1="+right$("0000000"+hex$(a%(1)-a%(0)),8)+"="+str$(a%(1)-a%(0))
 item_add 2,"a3-a2="+right$("0000000"+hex$(a%(2)-a%(1)),8)+"="+str$(a%(2)-a%(1))
 item_add 2,"a4-a3="+right$("0000000"+hex$(a%(3)-a%(2)),8)+"="+str$(a%(3)-a%(2))
 item_add 2,"a5-a4="+right$("0000000"+hex$(a%(4)-a%(3)),8)+"="+str$(a%(4)-a%(3))
 item_add 2,"--------------------------------"
end_if

for n%=0 to 4
  item_add 2,"adr indice "+str$(n%)+"="+hex$(a%(n%))
next n%
item_add 2,"========================"
item_add 3,"========================"
item_add 4,""
item_add 4,""
item_add 4,""

end_sub

Le résultat est correct. Mais la méthode est brutale et a quelques inconvénients. En particulier, si le tableau est supprimé via la commande FREE et recréé par DIM, les adresses doivent évidemment être recherchées à nouveau, ce qui pose le problème de la pérennité de ces valeurs.

Ceci, comme déjà indiqué dans un autre post, pourrait être résolu de deux manières:
1. création d'une fonction ADR_ARRAY(N,I1,I2) avec N=nom du tableau, I1 et I2 étant des indices
2. mémorisation de façon physiquement contigue des séries de données

Personnellement, à la vue de la gestion del'allocation de mémoire dynamique de Panoramic, je pense que la solution (2) est exclue. Par contre, une fonction ADR_ARRAY(N,I1,I2) est certainement faisable assez facilement:
Code:
dim a%, buf%(30,50)
a% = adr_array(buf%,3,0) : ' retourne l'adresse du début de la série 3 = cellule buf%(3,0)
a% = adr_array(buf%,17,23) : ' retourne l'adresse de la cellule buf%(17,23)

Un des objectifs de cette suggestion (mais pas le seul !) est de pouvoir faire des sauvegardes et restaurations très rapides des données de gros tableaux.

D'ailleurs, pour les 3 types de tableaux, les informatioins suivantes s'appliquent:
1. tableaux d'entiers: chaque cellule est un mot de 32 bits contenant un entier signé
2. tableau de flottants: chaque cellule est un mont long de 64 bits contenant un flottant
3. tableau de chaînes de caractères: chaque cellule est un mot de 32 bits contenant un pointeur de type pstring adresse de la chaîne de caractères terminée par un octet 0 et précédée de 2 mots contenant longueur et compteur d'utilisation

EDIT

Il va de soi que ce programme de démo a besoin de la version actuelle de KGF.dll, disponible au téléchargement sur mon site, mon site miroir ou mon WebDav, ainsi que par le lien dans ma signature !

P.S.

Ou est-ce qu'il y aurait un moyen, dans une DLL, de trouver les adresses des débuts des sections pour un tableau en deux dimensions ? A partir du nom d'une variable en chaîne de caractères, je peux retrouver son nombre de dimensions (0, 1 ou 2) et la ou les valeurs de ses dimensions (1 ou 2 valeurs). Mais les adresses de départ des sections de données pour chacune des valeurs du second indice ? Je n'ai pas encore réussi à trouver cela à partir de la DLL...
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://klauspanoramic.comxa.com/index.html
 
Adresses dans un tableau à 2 dimensions
Voir le sujet précédent Voir le sujet suivant Revenir en haut 
Page 1 sur 1
 Sujets similaires
-
» Staff dans un tableau (Info bulle)
» Ajouter un texte et des infobulles dans un tableau
» Symboles disparaissent dans un tableau
» Aller à la ligne dans un tableau
» Mettre une image de fond dans un tableau.

Permission de ce forum:Vous ne pouvez pas répondre aux sujets dans ce forum
FORUM DE DISCUSSION SUR LE LANGAGE PANORAMIC :: PANORAMIC 32 bits :: Présentation et bavardage-
Sauter vers: