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 |
|
|
| Adresses dans un tableau à 2 dimensions | |
| | Auteur | Message |
---|
Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
| Sujet: Adresses dans un tableau à 2 dimensions Dim 13 Nov 2016 - 3: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(). | |
| | | Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
| Sujet: Re: Adresses dans un tableau à 2 dimensions Mer 16 Nov 2016 - 0: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 EDITIl 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... | |
| | | | Adresses dans un tableau à 2 dimensions | |
|
Sujets similaires | |
|
| Permission de ce forum: | Vous ne pouvez pas répondre aux sujets dans ce forum
| |
| |
| |