RÉCUPÉRER UNE CHAINE DE CARACTÈRE À PARTIR DE SON POINTEUR D'ADRESSE MÉMOIRE

bouv Messages postés 1411 Date d'inscription mercredi 6 août 2003 Statut Membre Dernière intervention 3 mars 2019 - 8 août 2006 à 21:53
BIGDAMSBIG Messages postés 27 Date d'inscription dimanche 3 juin 2007 Statut Membre Dernière intervention 25 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.

https://codes-sources.commentcamarche.net/source/38998-recuperer-une-chaine-de-caractere-a-partir-de-son-pointeur-d-adresse-memoire

BIGDAMSBIG Messages postés 27 Date d'inscription dimanche 3 juin 2007 Statut Membre Dernière intervention 25 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és 2167 Date d'inscription mardi 11 novembre 2003 Statut Membre Dernière intervention 16 juillet 2009 1
9 mars 2007 à 21:31
Ok merci c'est fait ;)
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
9 mars 2007 à 21:00
<>0 fera l'affaire ^^

le signe, ca n'est qu'une question de représentation...
MadM@tt Messages postés 2167 Date d'inscription mardi 11 novembre 2003 Statut Membre Dernière intervention 16 juillet 2009 1
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és 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
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és 1411 Date d'inscription mercredi 6 août 2003 Statut Membre Dernière intervention 3 mars 2019 1
9 août 2006 à 19:52
TB, maintenant je peux noter.
10/10
MadM@tt Messages postés 2167 Date d'inscription mardi 11 novembre 2003 Statut Membre Dernière intervention 16 juillet 2009 1
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és 2167 Date d'inscription mardi 11 novembre 2003 Statut Membre Dernière intervention 16 juillet 2009 1
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és 2167 Date d'inscription mardi 11 novembre 2003 Statut Membre Dernière intervention 16 juillet 2009 1
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és 1411 Date d'inscription mercredi 6 août 2003 Statut Membre Dernière intervention 3 mars 2019 1
9 août 2006 à 17:41
PS : Comment se fait-il que tu n'ai que le pointeur de ta variable ?
bouv Messages postés 1411 Date d'inscription mercredi 6 août 2003 Statut Membre Dernière intervention 3 mars 2019 1
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és 2167 Date d'inscription mardi 11 novembre 2003 Statut Membre Dernière intervention 16 juillet 2009 1
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és 1411 Date d'inscription mercredi 6 août 2003 Statut Membre Dernière intervention 3 mars 2019 1
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és 2167 Date d'inscription mardi 11 novembre 2003 Statut Membre Dernière intervention 16 juillet 2009 1
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és 13272 Date d'inscription lundi 13 décembre 2004 Statut Membre Dernière intervention 3 février 2018 47
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és 2167 Date d'inscription mardi 11 novembre 2003 Statut Membre Dernière intervention 16 juillet 2009 1
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és 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
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és 2375 Date d'inscription jeudi 12 juillet 2001 Statut Modérateur Dernière intervention 15 décembre 2018 22
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és 2167 Date d'inscription mardi 11 novembre 2003 Statut Membre Dernière intervention 16 juillet 2009 1
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és 1411 Date d'inscription mercredi 6 août 2003 Statut Membre Dernière intervention 3 mars 2019 1
8 août 2006 à 21:53
Cela semble vraiment pas mal mais pourrais tu mettre un projet avec un exemple d'utilisation.