RÉCUPÉRER UNE CHAINE DE CARACTÈRE À PARTIR DE SON POINTEUR D'ADRESSE MÉMOIRE
bouv
Messages postés1411Date d'inscriptionmercredi 6 août 2003StatutMembreDernière intervention 3 mars 2019
-
8 août 2006 à 21:53
BIGDAMSBIG
Messages postés27Date d'inscriptiondimanche 3 juin 2007StatutMembreDernière intervention25 février 2008
-
13 janv. 2008 à 23:10
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.
BIGDAMSBIG
Messages postés27Date d'inscriptiondimanche 3 juin 2007StatutMembreDernière intervention25 février 2008 13 janv. 2008 à 23:10
SALUT
moi je trouve ca utile comme explication voulant gagner du temps a lire des fichiers de plus de 10 Mo en sachant qu'il ne seront pas modifiés au cour de mon programme.
je ne fais que de la lecture de donnéeS.et commencant les apis de windows je comprends mieux l'intéret de la reférence qui est comme prendre la valeur d'une adresse
seulement a un instant donnée un peu comme un pointeur.
merci d'apporter a mon ignorance un peu de clareté
c'est plus un tutorial qu'un code
finit les byval sur des donnees qui ne changent jamais
au cour de mon programme.
merci MadMAxx
MadM@tt
Messages postés2167Date d'inscriptionmardi 11 novembre 2003StatutMembreDernière intervention16 juillet 20091 9 mars 2007 à 21:31
Ok merci c'est fait ;)
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 9 mars 2007 à 21:00
<>0 fera l'affaire ^^
le signe, ca n'est qu'une question de représentation...
MadM@tt
Messages postés2167Date d'inscriptionmardi 11 novembre 2003StatutMembreDernière intervention16 juillet 20091 9 mars 2007 à 20:47
ah ouais ? je savais pas, c'est mieux que j'enlève totalement le test ou je met <> 0 selon toi ?
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 9 mars 2007 à 09:45
j'aime pas trop le > 0
en fait, en VB le Long est forcément signé...
ce qui fait que -123456 pourrait être un pointeur de chaine valide...
bouv
Messages postés1411Date d'inscriptionmercredi 6 août 2003StatutMembreDernière intervention 3 mars 20191 9 août 2006 à 19:52
TB, maintenant je peux noter.
10/10
MadM@tt
Messages postés2167Date d'inscriptionmardi 11 novembre 2003StatutMembreDernière intervention16 juillet 20091 9 août 2006 à 17:53
Oh non c'est bon, ça marche !!
(désolé pour vos boites mail ça aura fait un sacré troll)
J'avais juste oublié de mettre lstrlen(Str as ANY)
Merci bouv et PCPT pour votre aide
MadM@tt
Messages postés2167Date d'inscriptionmardi 11 novembre 2003StatutMembreDernière intervention16 juillet 20091 9 août 2006 à 17:51
Pfff j'y comprend vraiment rien, maintenant ce que j'ai fait, c'est que j'ai essayé de mettre en mémoire ma chaine de caractère manuellement, pour l'avoir dans ma variable mais également en mémoire.
J'ai donc utilisé les api :
Public Declare Function LocalFree Lib "kernel32" (ByVal hMem As Long) As Long
Public Declare Function LocalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal wBytes As Long) As Long
pour lui allouer un espace mémoire...
Et la ça marche, mais ça ne prend que 7 caractères.
J'ai mis la source à jour
MadM@tt
Messages postés2167Date d'inscriptionmardi 11 novembre 2003StatutMembreDernière intervention16 juillet 20091 9 août 2006 à 17:46
J'ai changé les déclarations (mais résoud pas le prob en tout cas, le problème à l'air déjà de venir de lstrlen car ça renvoie toujours 1, quelque soit la chaine entrée)
Sinon je ne pense pas que cette fonction agisse comme un ByRef vu qu'on copie la chaine, c'est plutot un ByVal. Je pense que tu fais référence à l'explication que j'ai mis plus haut, en fait je voulais dire que ça faisait comme un ByRef quand on passe l'adresse mémoire en parametre à une api, et un ByVal quand on lui passe la valeur. Après ici c'est différent car on veut récupérer la valeur de sortie d'une api dans une variable exploitable en vb (certaines api renvoie des pointeurs). Et justement je pense qu'il faut que je supprime la chaine de caractère en mémoire une fois récupéré sa valeur.
Sinon ça me sert la dedans (en gros) :
' Fait la liste des processus en mémoire à l'endroit désigné par le pointeur : pProcessInfo
' Count est le nombre de processus
Public Declare Function WTSEnumerateProcesses Lib "wtsapi32.dll" Alias "WTSEnumerateProcessesA" (ByVal hServer As Long, ByVal Reserved As Long, ByVal Version As Long, ByRef pProcessInfo As Long, ByRef Count As Long) As Long
' Libère la mémoire utilisée par la liste des processus crée avec la fonction d'au dessus
Public Declare Sub WTSFreeMemory Lib "wtsapi32.dll" (ByVal pMemory As Long)
' Pour faire la liste des processus
Public Type WTS_PROCESS_INFO
SessionID As Long ' Identificateur de la session
ProcessID As Long ' Identificateur du processus
pProcessName As Long ' Pointeur vers le nom du processus
pUserSid As Long ' Pointeur vers l'ID de l'utilisateur associé au processus
End Type
Je fais la liste des processus et dans mon type de sortie, j'ai un pointeur vers la chaine de caractère qui contient le nom des processus.
bouv
Messages postés1411Date d'inscriptionmercredi 6 août 2003StatutMembreDernière intervention 3 mars 20191 9 août 2006 à 17:41
PS : Comment se fait-il que tu n'ai que le pointeur de ta variable ?
bouv
Messages postés1411Date d'inscriptionmercredi 6 août 2003StatutMembreDernière intervention 3 mars 20191 9 août 2006 à 17:37
Après quelques recherches j'ai trouvé sur MSDN que lstrcpy doit être déclaré ainsi
Public Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" (ByVal lpString1 As Any, ByVal lpString2 As Any) As Long
Les parametres sont de type Any pour car il existe plusieurs utilisations de l'API.
Maintenant je pose 1 question :
Est-il sûr que l'utilisation de cette fonction est l'équivalent d'un ByRef (n'occupe pas de nouvel espace mémoire)?
MadM@tt
Messages postés2167Date d'inscriptionmardi 11 novembre 2003StatutMembreDernière intervention16 juillet 20091 9 août 2006 à 17:31
ben je ne suis pas censé avoir la variable string, seulement son pointeur, sinon aucun intéret...
enfin c'était ptet ironique ? lol
bouv
Messages postés1411Date d'inscriptionmercredi 6 août 2003StatutMembreDernière intervention 3 mars 20191 9 août 2006 à 16:50
en faisant
Public Function GetStringFromPtr(ByRef Pointeur As String) As String
cela peut valoir le coup ^^
MadM@tt
Messages postés2167Date d'inscriptionmardi 11 novembre 2003StatutMembreDernière intervention16 juillet 20091 9 août 2006 à 16:48
Merci d'avoir pris le temps de regarder mon code, simplement la je ne te suis pas.
La fonction sert à récupérer la chaine à partir d'un pointeur mémoire (donc un Long), à quoi ça sert que je lui passe la chaine que je veux récupérer ?
Et j'ai regardé la msdn, pour lstrlen ils disent que lpString (le parametre), c'est un pointeur vers une chaine terminée par un vbNullString (que dans mon exemple je n'ai d'ailleurs pas fait).
J'ai rajouté le vbNullString à la fin de ma variable mais ça rend pareil en tout cas.
PCPT
Messages postés13272Date d'inscriptionlundi 13 décembre 2004StatutMembreDernière intervention 3 février 201847 9 août 2006 à 16:37
salut,
l'erreur vient de tes déclarations.
elles ont besoins de chaînes (apparemment)
donc ton avant dernière ligne (Form) :
tStr = tStr + " GetStringFromPtr(" + Str$(StrPtr(VarExemple)) + ")=" + GetStringFromPtr(VarExemple)
et ton module :
Option Explicit
' permet de copier une chaine de caractère dans une autre
'Public Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" (ByVal lpString1 As String, ByVal lpString2 As Long) As Long
Public Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" (ByVal lpString1 As String, ByVal lpString2 As String) As Long
'Public Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" (ByVal lpString As Long) As Long
Public Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" (ByVal lpString As String) As Long
' Permet de récupérer la chaine de caractère en mémoire à partir de son pointeur
Public Function GetStringFromPtr(ByVal Pointeur As String) As String
If LenB(Pointeur) > 0 Then
GetStringFromPtr = Space(lstrlen(Pointeur))
lstrcpy GetStringFromPtr, ByVal Pointeur
End If
End Function
++ ;)
MadM@tt
Messages postés2167Date d'inscriptionmardi 11 novembre 2003StatutMembreDernière intervention16 juillet 20091 9 août 2006 à 15:52
Willi > Tu as complètement raison je n'y avais pas du tout pensé, dès que je résoud mon petit problème je l'y met.
Renfield > Merci pour l'info, j'ai mis à jour.
Par contre j'ai toujours un bug dans l'exemple que j'ai mis dans le zip, et j'ai remarqué que dans le prog où je l'utilise j'obtient quelque fois des erreurs. Quelqu'un voit d'où ça vient ?
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 9 août 2006 à 09:45
j'aime pas trop le coup du
Space(256)
lstrlen pourrait directement te filer la bonne taille a allouer
cs_Willi
Messages postés2375Date d'inscriptionjeudi 12 juillet 2001StatutModérateurDernière intervention15 décembre 201822 9 août 2006 à 09:11
Bonne démo, les prochaines fois pense à déposer ce genre de code tout pret (snippet) sur www.codyx.org.
Bonne continuation ++
MadM@tt
Messages postés2167Date d'inscriptionmardi 11 novembre 2003StatutMembreDernière intervention16 juillet 20091 8 août 2006 à 23:40
salut bouv, pas de problème pour l'exemple d'utilisation, je l'ai mis.
Mais je ne sais pas comment je me suis débrouillé, dans mon exemple ça marche pas lol... Oula je suis vraiment fatigué, pourtant dans mon prog qui l'utilise ça marche. Ici ça ne me renvoie que la première lettre du contenu de la chaine de caractère.
En meme temps, mon pc tourne depuis super longtemps et je lui en fait voir de toutes les couleurs avec mes tests sur ces api, depuis plusieurs heures je n'arrete pas d'avoir des "VB6 va etre fermé pour cause d'erreur, voulez vous envoyer un rapport à MS..." Et autres bugs
Je vais redémarrer et retenter voir si ça marche mieux.
Est ce que quelqu'un pourrait tester ce que j'ai mis voir si ça marche chez lui (ou alors si quelqu'un qui s'y connait voit une grossière erreur que j'ai fait dans mon code ^^)
Merci
bouv
Messages postés1411Date d'inscriptionmercredi 6 août 2003StatutMembreDernière intervention 3 mars 20191 8 août 2006 à 21:53
Cela semble vraiment pas mal mais pourrais tu mettre un projet avec un exemple d'utilisation.
13 janv. 2008 à 23:10
moi je trouve ca utile comme explication voulant gagner du temps a lire des fichiers de plus de 10 Mo en sachant qu'il ne seront pas modifiés au cour de mon programme.
je ne fais que de la lecture de donnéeS.et commencant les apis de windows je comprends mieux l'intéret de la reférence qui est comme prendre la valeur d'une adresse
seulement a un instant donnée un peu comme un pointeur.
merci d'apporter a mon ignorance un peu de clareté
c'est plus un tutorial qu'un code
finit les byval sur des donnees qui ne changent jamais
au cour de mon programme.
merci MadMAxx
9 mars 2007 à 21:31
9 mars 2007 à 21:00
le signe, ca n'est qu'une question de représentation...
9 mars 2007 à 20:47
9 mars 2007 à 09:45
en fait, en VB le Long est forcément signé...
ce qui fait que -123456 pourrait être un pointeur de chaine valide...
9 août 2006 à 19:52
10/10
9 août 2006 à 17:53
(désolé pour vos boites mail ça aura fait un sacré troll)
J'avais juste oublié de mettre lstrlen(Str as ANY)
Merci bouv et PCPT pour votre aide
9 août 2006 à 17:51
J'ai donc utilisé les api :
Public Declare Function LocalFree Lib "kernel32" (ByVal hMem As Long) As Long
Public Declare Function LocalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal wBytes As Long) As Long
pour lui allouer un espace mémoire...
Et la ça marche, mais ça ne prend que 7 caractères.
J'ai mis la source à jour
9 août 2006 à 17:46
Sinon je ne pense pas que cette fonction agisse comme un ByRef vu qu'on copie la chaine, c'est plutot un ByVal. Je pense que tu fais référence à l'explication que j'ai mis plus haut, en fait je voulais dire que ça faisait comme un ByRef quand on passe l'adresse mémoire en parametre à une api, et un ByVal quand on lui passe la valeur. Après ici c'est différent car on veut récupérer la valeur de sortie d'une api dans une variable exploitable en vb (certaines api renvoie des pointeurs). Et justement je pense qu'il faut que je supprime la chaine de caractère en mémoire une fois récupéré sa valeur.
Sinon ça me sert la dedans (en gros) :
' Fait la liste des processus en mémoire à l'endroit désigné par le pointeur : pProcessInfo
' Count est le nombre de processus
Public Declare Function WTSEnumerateProcesses Lib "wtsapi32.dll" Alias "WTSEnumerateProcessesA" (ByVal hServer As Long, ByVal Reserved As Long, ByVal Version As Long, ByRef pProcessInfo As Long, ByRef Count As Long) As Long
' Libère la mémoire utilisée par la liste des processus crée avec la fonction d'au dessus
Public Declare Sub WTSFreeMemory Lib "wtsapi32.dll" (ByVal pMemory As Long)
' Pour faire la liste des processus
Public Type WTS_PROCESS_INFO
SessionID As Long ' Identificateur de la session
ProcessID As Long ' Identificateur du processus
pProcessName As Long ' Pointeur vers le nom du processus
pUserSid As Long ' Pointeur vers l'ID de l'utilisateur associé au processus
End Type
Je fais la liste des processus et dans mon type de sortie, j'ai un pointeur vers la chaine de caractère qui contient le nom des processus.
9 août 2006 à 17:41
9 août 2006 à 17:37
Public Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" (ByVal lpString1 As Any, ByVal lpString2 As Any) As Long
Les parametres sont de type Any pour car il existe plusieurs utilisations de l'API.
Maintenant je pose 1 question :
Est-il sûr que l'utilisation de cette fonction est l'équivalent d'un ByRef (n'occupe pas de nouvel espace mémoire)?
9 août 2006 à 17:31
enfin c'était ptet ironique ? lol
9 août 2006 à 16:50
Public Function GetStringFromPtr(ByRef Pointeur As String) As String
cela peut valoir le coup ^^
9 août 2006 à 16:48
La fonction sert à récupérer la chaine à partir d'un pointeur mémoire (donc un Long), à quoi ça sert que je lui passe la chaine que je veux récupérer ?
Et j'ai regardé la msdn, pour lstrlen ils disent que lpString (le parametre), c'est un pointeur vers une chaine terminée par un vbNullString (que dans mon exemple je n'ai d'ailleurs pas fait).
J'ai rajouté le vbNullString à la fin de ma variable mais ça rend pareil en tout cas.
9 août 2006 à 16:37
l'erreur vient de tes déclarations.
elles ont besoins de chaînes (apparemment)
donc ton avant dernière ligne (Form) :
tStr = tStr + " GetStringFromPtr(" + Str$(StrPtr(VarExemple)) + ")=" + GetStringFromPtr(VarExemple)
et ton module :
Option Explicit
' permet de copier une chaine de caractère dans une autre
'Public Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" (ByVal lpString1 As String, ByVal lpString2 As Long) As Long
Public Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" (ByVal lpString1 As String, ByVal lpString2 As String) As Long
'Public Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" (ByVal lpString As Long) As Long
Public Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" (ByVal lpString As String) As Long
' Permet de récupérer la chaine de caractère en mémoire à partir de son pointeur
Public Function GetStringFromPtr(ByVal Pointeur As String) As String
If LenB(Pointeur) > 0 Then
GetStringFromPtr = Space(lstrlen(Pointeur))
lstrcpy GetStringFromPtr, ByVal Pointeur
End If
End Function
++ ;)
9 août 2006 à 15:52
Renfield > Merci pour l'info, j'ai mis à jour.
Par contre j'ai toujours un bug dans l'exemple que j'ai mis dans le zip, et j'ai remarqué que dans le prog où je l'utilise j'obtient quelque fois des erreurs. Quelqu'un voit d'où ça vient ?
9 août 2006 à 09:45
Space(256)
lstrlen pourrait directement te filer la bonne taille a allouer
9 août 2006 à 09:11
Bonne continuation ++
8 août 2006 à 23:40
Mais je ne sais pas comment je me suis débrouillé, dans mon exemple ça marche pas lol... Oula je suis vraiment fatigué, pourtant dans mon prog qui l'utilise ça marche. Ici ça ne me renvoie que la première lettre du contenu de la chaine de caractère.
En meme temps, mon pc tourne depuis super longtemps et je lui en fait voir de toutes les couleurs avec mes tests sur ces api, depuis plusieurs heures je n'arrete pas d'avoir des "VB6 va etre fermé pour cause d'erreur, voulez vous envoyer un rapport à MS..." Et autres bugs
Je vais redémarrer et retenter voir si ça marche mieux.
Est ce que quelqu'un pourrait tester ce que j'ai mis voir si ça marche chez lui (ou alors si quelqu'un qui s'y connait voit une grossière erreur que j'ai fait dans mon code ^^)
Merci
8 août 2006 à 21:53