FORUM DE DISCUSSION SUR LE LANGAGE PANORAMIC
Vous souhaitez réagir à ce message ? Créez un compte en quelques clics ou connectez-vous pour continuer.
FORUM DE DISCUSSION SUR LE LANGAGE PANORAMIC

Développement d'applications avec le langage Panoramic
 
AccueilAccueil  RechercherRechercher  Dernières imagesDernières images  S'enregistrerS'enregistrer  MembresMembres  Connexion  
Derniers sujets
» PANORAMIC V 1
Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) Emptypar papydall Aujourd'hui à 15:10

» Gestion d'un système client-serveur.
Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) Emptypar Klaus Aujourd'hui à 13:18

» Editeur EliP 6 : Le Tiny éditeur avec 25 onglets de travail
Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) Emptypar Froggy One Aujourd'hui à 11:16

» @Jack
Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) Emptypar Jack Mar 30 Avr 2024 - 20:40

» trop de fichiers en cours
Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) Emptypar papydall Lun 29 Avr 2024 - 23:39

» Une calculatrice en une ligne de programme
Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) Emptypar jean_debord Dim 28 Avr 2024 - 8:47

» Form(résolu)
Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) Emptypar leclode Sam 27 Avr 2024 - 17:59

» Bataille navale SM
Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) Emptypar jjn4 Ven 26 Avr 2024 - 17:39

» Les maths du crocodile
Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) Emptypar jean_debord Jeu 25 Avr 2024 - 10:37

» Naissance de Crocodile Basic
Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) Emptypar jean_debord Jeu 25 Avr 2024 - 8:45

» Dessine-moi une galaxie
Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) Emptypar jjn4 Lun 22 Avr 2024 - 13:47

» Erreur END_SUB
Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) Emptypar jjn4 Lun 22 Avr 2024 - 13:43

» Bug sur DIM_LOCAL ?
Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) Emptypar papydall Dim 21 Avr 2024 - 23:30

» 2D_fill_color(résolu)
Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) Emptypar leclode Sam 20 Avr 2024 - 8:32

» Consommation gaz électricité
Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) Emptypar leclode Mer 17 Avr 2024 - 11:07

Navigation
 Portail
 Index
 Membres
 Profil
 FAQ
 Rechercher
Rechercher
 
 

Résultats par :
 
Rechercher Recherche avancée
Mai 2024
LunMarMerJeuVenSamDim
  12345
6789101112
13141516171819
20212223242526
2728293031  
CalendrierCalendrier
Le deal à ne pas rater :
Jeux, jouets et Lego : le deuxième à -50% (large sélection)
Voir le deal

 

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

Aller en bas 
5 participants
AuteurMessage
silverman

silverman


Nombre de messages : 968
Age : 51
Localisation : Picardie
Date d'inscription : 18/03/2015

Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) Empty
MessageSujet: Astuce : créer mémoire tampon(très utile pour CALL_DLLx())   Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) EmptySam 25 Avr 2015 - 18: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 - 13:25, édité 11 fois
Revenir en haut Aller en bas
Jicehel

Jicehel


Nombre de messages : 5947
Age : 51
Localisation : 77500
Date d'inscription : 18/04/2011

Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) Empty
MessageSujet: Re: Astuce : créer mémoire tampon(très utile pour CALL_DLLx())   Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) EmptySam 25 Avr 2015 - 18: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
papydall

papydall


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

Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) Empty
MessageSujet: Re: Astuce : créer mémoire tampon(très utile pour CALL_DLLx())   Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) EmptySam 25 Avr 2015 - 19: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
http://papydall-panoramic.forumarabia.com/
Klaus

Klaus


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

Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) Empty
MessageSujet: Re: Astuce : créer mémoire tampon(très utile pour CALL_DLLx())   Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) EmptySam 25 Avr 2015 - 19: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
http://klauspanoramic.comxa.com/index.html En ligne
Nardo26

Nardo26


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

Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) Empty
MessageSujet: Re: Astuce : créer mémoire tampon(très utile pour CALL_DLLx())   Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) EmptySam 25 Avr 2015 - 20: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à : https://panoramic.1fr1.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
http://nardo26.lescigales.org
silverman

silverman


Nombre de messages : 968
Age : 51
Localisation : Picardie
Date d'inscription : 18/03/2015

Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) Empty
MessageSujet: Re: Astuce : créer mémoire tampon(très utile pour CALL_DLLx())   Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) EmptySam 25 Avr 2015 - 21: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
Klaus

Klaus


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

Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) Empty
MessageSujet: Re: Astuce : créer mémoire tampon(très utile pour CALL_DLLx())   Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) EmptyDim 26 Avr 2015 - 1: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
http://klauspanoramic.comxa.com/index.html En ligne
Nardo26

Nardo26


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

Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) Empty
MessageSujet: Re: Astuce : créer mémoire tampon(très utile pour CALL_DLLx())   Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) EmptyDim 26 Avr 2015 - 1: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)  Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) 07

@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
http://nardo26.lescigales.org
Jicehel

Jicehel


Nombre de messages : 5947
Age : 51
Localisation : 77500
Date d'inscription : 18/04/2011

Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) Empty
MessageSujet: Re: Astuce : créer mémoire tampon(très utile pour CALL_DLLx())   Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) EmptyDim 26 Avr 2015 - 10: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
silverman

silverman


Nombre de messages : 968
Age : 51
Localisation : Picardie
Date d'inscription : 18/03/2015

Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) Empty
MessageSujet: Re: Astuce : créer mémoire tampon(très utile pour CALL_DLLx())   Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) EmptyDim 26 Avr 2015 - 11: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:
https://panoramic.1fr1.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 - 13:51, édité 1 fois
Revenir en haut Aller en bas
Jicehel

Jicehel


Nombre de messages : 5947
Age : 51
Localisation : 77500
Date d'inscription : 18/04/2011

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

Absolument on a de quoi faire avec ces différentes méthodes Wink
Revenir en haut Aller en bas
Nardo26

Nardo26


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

Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) Empty
MessageSujet: Re: Astuce : créer mémoire tampon(très utile pour CALL_DLLx())   Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) EmptyDim 26 Avr 2015 - 17: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... Astuce : créer mémoire tampon(très utile pour CALL_DLLx()) 14
Revenir en haut Aller en bas
http://nardo26.lescigales.org
Contenu sponsorisé





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

Revenir en haut Aller en bas
 
Astuce : créer mémoire tampon(très utile pour CALL_DLLx())
Revenir en haut 
Page 1 sur 1
 Sujets similaires
-
» Créer mémoire tampon, application
» Aide-mémoire des mots-clés Panoramic
» Utile pour Noêl
»  GetParent : Utile pas pour deux sous
» pour memoire

Permission de ce forum:Vous ne pouvez pas répondre aux sujets dans ce forum
FORUM DE DISCUSSION SUR LE LANGAGE PANORAMIC :: PANORAMIC :: Vos sources, vos utilitaires à partager-
Sauter vers: