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
» Problème de compilateur.
par Pedro Alvarez Hier à 20:01

» COMPILATEUR V 0.9 beta 8 du 18 aout 2017
par Pedro Alvarez Hier à 19:54

» Pb 17 (en analyse): ITEM_SELECT ne fonctionne pas
par Jack Jeu 17 Aoû 2017 - 19:26

» Compilateur FBPano
par Mike Jeu 17 Aoû 2017 - 13:52

» un nouveau editeur panobasic
par Jean Claude Jeu 17 Aoû 2017 - 10:18

» Le compilateur.
par Pedro Alvarez Jeu 17 Aoû 2017 - 8:36

» Pb 16 (en analyse): ON_CLOSE plante à l'exécution
par Jack Mer 16 Aoû 2017 - 20:00

» Pb 15 (en analyse): TIMER_ON plante à l'exécution
par Jack Mer 16 Aoû 2017 - 19:58

» KGF_dll - nouvelles versions
par Yannick Dim 13 Aoû 2017 - 17:35

» probleme d'outil
par Yannick Dim 13 Aoû 2017 - 17:32

» Carte de France des régions
par Yannick Sam 12 Aoû 2017 - 21:33

» Pb 14 (en analyse): PRINT_LOCATE plante à l'exécution
par Jack Ven 11 Aoû 2017 - 22:37

» Petit avertissement [Mots réservés]
par papydall Ven 11 Aoû 2017 - 13:45

» Distances sur plan
par JL35 Jeu 10 Aoû 2017 - 21:29

» Tracé : Triangle, Carrée, Dents de scie, Sinusoïde redressée
par papydall Jeu 10 Aoû 2017 - 14:52

Navigation
 Portail
 Index
 Membres
 Profil
 FAQ
 Rechercher
Rechercher
 
 

Résultats par :
 
Rechercher Recherche avancée
Août 2017
LunMarMerJeuVenSamDim
 123456
78910111213
14151617181920
21222324252627
28293031   
CalendrierCalendrier

Partagez | 
 

 Astuce : créer mémoire tampon(très utile pour CALL_DLLx())

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

avatar

Nombre de messages : 464
Age : 45
Localisation : Picardie
Date d'inscription : 19/03/2015

MessageSujet: Astuce : créer mémoire tampon(très utile pour CALL_DLLx())   Sam 25 Avr 2015 - 19:39

EDIT2: qq changement dant le source pour être compatible avec la bibliothèque ici : créer memoire tampon, application
EDIT1: qq correction de phrase dans le post et le source pour améliorer la compréhension.

Bonjour à tous,

Lorsque l'on utilise une dll, on a parfois besoin de lui passer un pointeur qui pointe vers une mémoire tampon, pour récupérer des données par exemple.
Je n'ai pas trouvé de code sur le forum pour faire ça(j'ai peut être mal charché aussi cyclops ), alors voici mon astuce en Panoramic pur, sans DLL.

Le principe est simple:
- fabriquer une chaine de caractère de longueur voulu, avec le caractère null(chr$(0)).(Ca donne des octets null)
- récupérer avec ADR() le pointeur de cette chaine, pointeur qui est l'adresse ou sont stocké les octets null
---> cette adresse permet de lire/modifier ces octets, opération effectué à l'aide d'une sub()

C'est de l'écriture direct dans l'octet, il n'y a pas d'intermédiaire avec des chaines de caractères. Pas besoin de fonction comme LEFT,INSTR,..., rien du tout. La valeur stocké dans la mémoire tampon est copié directement dans la variable utilisateur.

Précaution à prendre : si on modifie un octet qui est en dehors de la mémoire tampon, on déclenche le mécanisme de protection de Windows, à savoir le fameux "ACCESS VIOLATION", donc être rigoureux quant on code Very Happy

En exemple, "GetCursorPos" de la DLL user32:
Code:

' Panoramic 0.9.25

'   ==============================================================
'   =  Title  : GetCursorPos
'   =
'   =  Author : Silverman
'   =
'   =  Date   : Avril 2015
'   =
'   =  Version: 1.1
'   ==============================================================
'   Comments  : Créer une mémoire tampon pour DLL.
'             : Exemple avec la fonction User32 : GetCursorPos
'   ==============================================================


' Attention au type de données:( plus d'info ici : https://msdn.microsoft.com/en-us/library/cc230318.aspx )
'
'    LONG = 4 bytes ---> entier signé, donc la variable de stockage d'un LONG se termine par %(x%,y%,...)
'
'    pointeur : DWORD
'    DWORD=4 bytes non signé; ce type n'existe pas en Panoramic, mais on peut le remplacer par
'    un LONG à condition qu'il soit toujours positif. Ex. de DWORD: lpPoint_ptr%
'
' lpPoint$ = structure POINT; détail ici : https://msdn.microsoft.com/fr-fr/library/windows/desktop/dd162805%28v=vs.85%29.aspx
'
' les valeurs retournées dans la structure POINT sont : 2 LONG
'
' GetCursorPos; détail ici : https://msdn.microsoft.com/fr-fr/library/windows/desktop/ms648390%28v=vs.85%29.aspx



' NB: si on essaye de lire des données en deçà ou au-delà de la taille du buffer que l'on à créé, il y a le risque de déclencher
'     le système de protection de WINDOWS, à savoir le célèbre... "ACCESS VIOLATION".
'



' données pour le buffer
dim lpPoint$
dim lpPoint_ptr%

' créer un buffer pour 2 LONG(donc 8 bytes) nuls
lpPoint$=string$(8,chr$(0))

' copie le CONTENU de adr(lpPoint$), dans lpPoint_ptr%.(NB: Le contenu de adr(lpPoint$) est l'adresse réelle du buffer)
GET_BUFFER_PTR(adr(lpPoint_ptr%),adr(lpPoint$))


' données pour la démo
dim bool
dim x%
dim y%

alpha 1

dll_on "user32"

repeat
   ' bool retourne une valeur non nulle si l'appel à la fonction est un succès; pas utile ici.
   ' ATTENTION !! il faut tenir compte de la casse. "GetCursorPos"--->ok , "getcursorpos"--->erreur
   bool=dll_call1("GetCursorPos",lpPoint_ptr%)

   ' copie les valeurs des coordonnées souris contenu dans le buffer, dans les variables x% et y%
   READ_BUFFER_LONG(adr(x%),lpPoint_ptr%,0)
   READ_BUFFER_LONG(adr(y%),lpPoint_ptr%,4)

   ' affichage du résultat
   caption 1,"X = "+str$(x%)+"          Y = "+str$(y%)

until scancode<>0

END
sub READ_BUFFER_LONG(adr_destination%,adr_source%,buffer_position%)
' LONG = 4 BYTEs
' adr_destination%  = adresse destination
' adr_source%       = adresse adr_source
' copie un LONG, –2147483648 < LONG < 2147483647
   poke adr_destination%,peek(adr_source%+buffer_position%)
   poke adr_destination%+1,peek(adr_source%+1+buffer_position%)
   poke adr_destination%+2,peek(adr_source%+2+buffer_position%)
   poke adr_destination%+3,peek(adr_source%+3+buffer_position%)
end_sub

sub GET_BUFFER_PTR(adr_destination%,adr_source%)
' retrouve l'adresse du pointeur
   poke adr_destination%,peek(adr_source%)
   poke adr_destination%+1,peek(adr_source%+1)
   poke adr_destination%+2,peek(adr_source%+2)
   poke adr_destination%+3,peek(adr_source%+3)
end_sub


Dernière édition par silverman le Lun 27 Avr 2015 - 14:25, édité 11 fois
Revenir en haut Aller en bas
Voir le profil de l'utilisateur
Jicehel

avatar

Nombre de messages : 5849
Age : 45
Localisation : 77500
Date d'inscription : 19/04/2011

MessageSujet: Re: Astuce : créer mémoire tampon(très utile pour CALL_DLLx())   Sam 25 Avr 2015 - 19:51

Si, ça a déjà était indiqué par Klaus, mais ça ne retire rien au fait que ce soit bien de le partager proprement comme dans ton post. Ce genre d'astuces est toujours bonne à rappeler car ce n'est pas du tout inné ou facile à trouver.
De plus Klaus utilisait la chaine de caractères et pas les pokes, ton approche est donc très interssante
Revenir en haut Aller en bas
Voir le profil de l'utilisateur
papydall

avatar

Nombre de messages : 5508
Age : 67
Localisation : Moknine (Tunisie) Entre la chaise et le clavier
Date d'inscription : 03/03/2012

MessageSujet: Re: Astuce : créer mémoire tampon(très utile pour CALL_DLLx())   Sam 25 Avr 2015 - 20:04

Je pense qu’on est devant deux approches différentes : celle de klaus et celle (très astucieuse) de Silverman.
Merci pour le partage, silverman. king
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://papydall-panoramic.forumarabia.com/
Klaus

avatar

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

MessageSujet: Re: Astuce : créer mémoire tampon(très utile pour CALL_DLLx())   Sam 25 Avr 2015 - 20:06

Ce que je préconise, habituellement, pour les fonctions de KGF.dll qui retournent une chaine de caractères, c'est de faire une chaîne par s$=string$(255," "). 255 est bien sûr juste un exemple. Ensuite, on passe adr(s$) en paramètre à la fonction. Et pour finir, on fait s$=trim$(s$).

Comment ça marche ? Mes fonctions copient du texte dans la zone mémoire pointée par adr(s$), et arrête la copie lorsque la première des deux conditions suivantes survient:
1. il n'y a plus de caractères à copier
2. l'octet en mémoire censé recevoir le prochain caractère est un NULL (zéro binaire).

La condition (2) est la sécurité pour éviter d'écrire au-delà de l'espace alloué à une variable de type chaîne de caractères. Les données de telles variables Panoramic sont toujours terminées par un octet NULL.

Donc, si tu crées une chaîne par s$=string$(255,chr$(0)), tu n'obtiendras jamais les données que la fonction doit retourner, car dès le premier caractère, elle va tomber sur un octet NULL et arrête la copie.

Pour résumer, ce qu'il faut faire:
Code:
dim s$, res%
s$ = string$(300," ")
res% = dll_callx("MaFonction",...,adr(s$),...)
s$ = trim$(s$)

Bien entendu, cette réflexion n'est valable que pour un appel à des fonctions de KGF.dll. Pour un appel d'autres DLLs comme User32.dll etc, la technique faisant l'objet de post est parfaitement applicable.
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://klauspanoramic.comxa.com/index.html
Nardo26

avatar

Nombre de messages : 2294
Age : 49
Localisation : Valence
Date d'inscription : 02/07/2010

MessageSujet: Re: Astuce : créer mémoire tampon(très utile pour CALL_DLLx())   Sam 25 Avr 2015 - 21:00

L'ideal serait d'avoir l'adresse exacte où se trouve par exemple les données d'un tableau d'entier.
C'est cette adresse là qu'il faudrait passer en parametre : les données seraient de suite dispo en Panoramic.
On avait déjà prospecté dans ce sens là : http://panoramic.free-boards.net/t2572-pic-et-poc-les-joyeux-drilles

Mais apparemment, les structures ont évoluées... (ou la fonction ADR a été retravaillée : les progs qui marchaient avant, ne fonctionnent plus)
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://nardo26.lescigales.org
silverman

avatar

Nombre de messages : 464
Age : 45
Localisation : Picardie
Date d'inscription : 19/03/2015

MessageSujet: Re: Astuce : créer mémoire tampon(très utile pour CALL_DLLx())   Sam 25 Avr 2015 - 22:13

@Nardo26
vraiment très intéressant ce lien, je ne l'avais pas trouvé dans mes recherches sur peek.

@Klaus
je suis habitué à créer des mémoires tampon de taille fixe, et par défaut elles sont initialisées avec des 0. C'est la façon de procéder pour utiliser les dlls windows.
C'est la première fois que je vois une mémoire tampon initialisé avec la valeur 32, et ça me déroute. Je n'ai pas du tout saisi les explication que tu as données; aurait tu un code très court pour que je puisse tester?
Revenir en haut Aller en bas
Voir le profil de l'utilisateur
Klaus

avatar

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

MessageSujet: Re: Astuce : créer mémoire tampon(très utile pour CALL_DLLx())   Dim 26 Avr 2015 - 2:03

Facile ! Prenons ma fonction qui retourne la version de KGF.dll. Elle retourne une valeur numérique comme résultat de la fonction, et une chaine de caractères de 25 caractères de long, pour la description textuelle:
Code:
dim vers$, vers%

dll_on "KGF.dll"

vers$ = string$(40,chr$(0))
vers% = DLL_call1("KGFdllVersion", adr(vers$) )
message str$(vers%)+" correspond à "+vers$

vers$ = string$(40," ")
vers% = DLL_call1("KGFdllVersion", adr(vers$) )
vers$ = trim$(vers$)
message str$(vers%)+" correspond à "+vers$

Tu verras aisément la différence de comportement...
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://klauspanoramic.comxa.com/index.html
Nardo26

avatar

Nombre de messages : 2294
Age : 49
Localisation : Valence
Date d'inscription : 02/07/2010

MessageSujet: Re: Astuce : créer mémoire tampon(très utile pour CALL_DLLx())   Dim 26 Avr 2015 - 2:13

Tu as raison Klaus, mais cela marche pour des appels a des fct de ta DLL. (car tu intègres le pointeur de chaine)  

@Silverman :
J'ai pas d'exemple sous le coude mais l'utilisation d'une chaine de caractères en tant que buffer pour une DLL système pose problème.
En effet, la fct ADR() ne te renvoie pas l'adresse de la zone mémoire qui contient la chaine de caractères mais elle te donne un pointeur sur cette adresse.

Donc une petite manipulation s'impose avant de pouvoir passer une adresse de buffer :

Code:
DIM buffer$
DIM ptr%,ret%
DIM i

buffer$="Exemple de buffer pour appel à une fct d'une DLL système"
ptr%=adr(buffer$)
dll_on "kernel32.dll"
' on récupère le pointeur sur la chaine de caractères et on le stocke dans la variable ptr%
ret%=DLL_CALL3("RtlMoveMemory",adr(ptr%),ptr%,4)
dll_off
' A partir de là, ptr% contient la véritable adresse où débute la chaine de caractères (le buffer).
' tu peux y mettre ce que tu veux, à l'aide de POKE en faisant attention de ne pas déborder bien sur...

' exemple: on récupère le contenu du "buffer" à l'aide de peek
FOR i=0 TO LEN(buffer$)-1
  PRINT CHR$(PEEK(ptr%+i));
NEXT i
Maintenant le contenu initial de la chaine importe peu car c'est à toi d'y mettre les données nécessaires...
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://nardo26.lescigales.org
Jicehel

avatar

Nombre de messages : 5849
Age : 45
Localisation : 77500
Date d'inscription : 19/04/2011

MessageSujet: Re: Astuce : créer mémoire tampon(très utile pour CALL_DLLx())   Dim 26 Avr 2015 - 11:29

Voir l'autre poste où Nardo donne les fonctions pour remplir la chaine de caractères simplement Wink
Revenir en haut Aller en bas
Voir le profil de l'utilisateur
silverman

avatar

Nombre de messages : 464
Age : 45
Localisation : Picardie
Date d'inscription : 19/03/2015

MessageSujet: Re: Astuce : créer mémoire tampon(très utile pour CALL_DLLx())   Dim 26 Avr 2015 - 12:58

@Klaus
Merci, j'essaye ça.

@Nardo26

Nardo26 a écrit:

En effet, la fct ADR() ne te renvoie pas l'adresse de la zone mémoire qui contient la chaine de caractères mais elle te donne un pointeur sur cette adresse.
Tout à fait, et je lis ce pointeur d'adresse avec la sub GET_BUFFER_PTR(sub qui recopie cette adresse dans une variable utilisateur), et c'est ce que tu fais avec "RtlMoveMemory". Je n'ai pas utilisé "RtlMoveMemory" du kernel32 pour les copies mémoires car on ne peut utiliser qu'une seule dll à la fois, c'est pour ça que je l'ai fait en Panoramic pur.

silverman a écrit:

- récupérer le pointeur de cette chaine, pointeur qui pointe sur un second pointeur
mais je me rend compte que cette explication est confuse, j'ai édité mon premier post pour corriger cela.

L'idée de créer une mémoire tampon m'est venu à la suite d'un post dans lequel je met un code utilisant user32. On peut le trouver ici, tout en bas de la page:
http://panoramic.free-boards.net/t3520-re-tout-le-monde-d
J'avais solutionné le probleme en utilisant la fonction "SetCursorPos". A la suite de quoi, des liens vers qq fonctions des dlls windows ont été postés. Mais sans mémoire tampon, on ne peut pas en utiliser beaucoup.

Cette astuce permet aux Panoramicien(ne)s de "bidouiller" avec les dlls systèmes.(Testeur fou, à vos clavier! lol! )


Dernière édition par silverman le Lun 27 Avr 2015 - 14:51, édité 1 fois
Revenir en haut Aller en bas
Voir le profil de l'utilisateur
Jicehel

avatar

Nombre de messages : 5849
Age : 45
Localisation : 77500
Date d'inscription : 19/04/2011

MessageSujet: Re: Astuce : créer mémoire tampon(très utile pour CALL_DLLx())   Dim 26 Avr 2015 - 16:31

Absolument on a de quoi faire avec ces différentes méthodes Wink
Revenir en haut Aller en bas
Voir le profil de l'utilisateur
Nardo26

avatar

Nombre de messages : 2294
Age : 49
Localisation : Valence
Date d'inscription : 02/07/2010

MessageSujet: Re: Astuce : créer mémoire tampon(très utile pour CALL_DLLx())   Dim 26 Avr 2015 - 18:01

silverman a écrit:
[...]Mais sans mémoire tampon, on ne peut pas en utiliser beaucoup.
Sans compter qu'il faut aussi que la fct renvoie une valeur booléenne...
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://nardo26.lescigales.org
Contenu sponsorisé




MessageSujet: Re: Astuce : créer mémoire tampon(très utile pour CALL_DLLx())   

Revenir en haut Aller en bas
 
Astuce : créer mémoire tampon(très utile pour CALL_DLLx())
Voir le sujet précédent Voir le sujet suivant Revenir en haut 
Page 1 sur 1
 Sujets similaires
-
» Astuce de la semaine: un selecteur de thème pour vos membres
» [Résolu] Vidéo et mémoire tampon
» La Freebox révolution : utile pour moi ?
» Augmenter Mémoire Tampon
» Application TV pour tablette HD

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 :: Vos sources, vos utilitaires à partager-
Sauter vers: