Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

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


Information sur la source

Catégorie :API Classé sous : pointeur, string, chaine, adresse, mémoire Niveau : Débutant Date de création : 08/08/2006 Date de mise à jour : 09/03/2007 21:34:17 Vu / téléchargé: 7 303 / 501

Note :
10 / 10 - par 3 personnes
10,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (20)
Ajouter un commentaire et/ou une note


Description

Bonjour à tous,

Voilà rien d'exceptionnel, tous les codeurs d'api en ont une comme ça, mais j'ai été confronté au problème d'avoir le pointeur d'une chaine de caractère mais pas sa valeur je pense que je ne suis pas tout seul.

Donc voilà, j'espère que ça servira ceux qui savent parfaitement à quoi ça peut leur servir (après un appel d'api généralement), sinon pour ceux qui ont des problèmes à comprendre les histoires de pointeurs et adresses mémoires (comme moi il y a quelques mois), j'ai mis une petite explication (si j'ai dit des trucs faux corrigez moi ;)
 

Source

  • ' A placer dans un module
  • ' permet de copier une chaine de caractère dans une autre
  • Public Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" (ByVal lpString1 As Any, ByVal lpString2 As Any) As Long
  • Public Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" (ByVal lpString As Any) As Long
  • ' Permet de récupérer la chaine de caractère en mémoire à partir de son pointeur
  • Public Function GetStringFromPtr(ByVal lPointeur As Long) As String
  • If lPointeur <> 0 Then
  • GetStringFromPtr = Space(lstrlen(lPointeur))
  • lstrcpy GetStringFromPtr, lPointeur
  • End If
  • End Function
  • Pour ceux qui ne comprennent pas ce que c'est que les adresses mémoire et tout ça :
  • Chaque variable que nous utilisons en vb possède une valeur qui est stockée en mémoire.
  • Seulement, elle est stocké à un endroit précis en mémoire, pour pas se mélanger,
  • chaque variable a un petit espace mémoire réservé pour y mettre sa valeur.
  • Pour savoir où se trouve cette adresse mémoire, il faut la repérer, et par convention
  • on la repère par une adresse numérique que l'on appelle "pointeur" (l'adresse pointe vers la valeur de la variable quoi...).
  • à quoi ça sert : pour appeler une fonction avec des parametres,
  • si on lui passait en parametre les valeurs des variables (genre des string, long, objets, listview etc....),
  • ça voudrait dire prendre la chaine de caractère (par exemple), prendre sa valeur et
  • la "copier" pour la donner à la fonction... si la chaine de caractère est longue, on perd beaucoup de mémoire...
  • Alors pour économiser de la mémoire, on passe juste en parametre le pointeur de la
  • chaine de caractère, comme ça la chaine existe en un seul exemplaire, à l'adresse
  • mémoire numéro XXXXXX, et la fonction va travailler sur la chaine de caractère qui
  • existe déjà en mémoire plutot que de la copier dans un autre espace mémoire.
  • En gros, c'est le principe du ByVal, ByRef.
  • ByVal (valeur de la variable) : on passe la valeur en parametre : donc on copie la
  • valeur, on perd bcp de mémoire
  • ByRef (la variable elle-meme, c'est à dire son pointeur mémoire) : on passe l'adresse
  • en parametre, donc on gagne en mémoire. MAIS (attention), il faut se souvenir que la
  • fonction aura alors accès directement à notre variable qu'on lui a passé en parametre,
  • si elle modifie sa valeur dans la fonction, cela touchera également la variable du
  • programme principal... Des fois c'est un avantage, des fois un inconvénient...
  • (note : cela n'arrive pas avec ByVal)
  • A vous de voir, j'espère que vous y voyez un peu plus clair.
' A placer dans un module

' permet de copier une chaine de caractère dans une autre
Public Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" (ByVal lpString1 As Any, ByVal lpString2 As Any) As Long
Public Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" (ByVal lpString As Any) As Long

' Permet de récupérer la chaine de caractère en mémoire à partir de son pointeur
Public Function GetStringFromPtr(ByVal lPointeur As Long) As String
    If lPointeur <> 0 Then
        GetStringFromPtr = Space(lstrlen(lPointeur))
        lstrcpy GetStringFromPtr, lPointeur
    End If
End Function






Pour ceux qui ne comprennent pas ce que c'est que les adresses mémoire et tout ça :

Chaque variable que nous utilisons en vb possède une valeur qui est stockée en mémoire.
Seulement, elle est stocké à un endroit précis en mémoire, pour pas se mélanger,
chaque variable a un petit espace mémoire réservé pour y mettre sa valeur.
Pour savoir où se trouve cette adresse mémoire, il faut la repérer, et par convention
on la repère par une adresse numérique que l'on appelle "pointeur" (l'adresse pointe vers la valeur de la variable quoi...).

à quoi ça sert : pour appeler une fonction avec des parametres,
si on lui passait en parametre les valeurs des variables (genre des string, long, objets, listview etc....),
ça voudrait dire prendre la chaine de caractère (par exemple), prendre sa valeur et
la "copier" pour la donner à la fonction... si la chaine de caractère est longue, on perd beaucoup de mémoire...
Alors pour économiser de la mémoire, on passe juste en parametre le pointeur de la
chaine de caractère, comme ça la chaine existe en un seul exemplaire, à l'adresse
mémoire numéro XXXXXX, et la fonction va travailler sur la chaine de caractère qui
existe déjà en mémoire plutot que de la copier dans un autre espace mémoire.

En gros, c'est le principe du ByVal, ByRef.
ByVal (valeur de la variable) : on passe la valeur en parametre : donc on copie la
valeur, on perd bcp de mémoire
ByRef (la variable elle-meme, c'est à dire son pointeur mémoire) : on passe l'adresse
en parametre, donc on gagne en mémoire. MAIS (attention), il faut se souvenir que la
fonction aura alors accès directement à notre variable qu'on lui a passé en parametre,
si elle modifie sa valeur dans la fonction, cela touchera également la variable du
programme principal... Des fois c'est un avantage, des fois un inconvénient...
(note : cela n'arrive pas avec ByVal)

A vous de voir, j'espère que vous y voyez un peu plus clair.

Conclusion

Je compte sur vous pour me signaler s'il y a des bugs ;)


Une petite question également : Une fois qu'on a récupérer la chaine de caractère, faut-il libérer l'espace mémoire concerné (vu que c'est stocké dans une variable vb) ?
 

Fichier Zip

Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip

Historique

08 août 2006 23:37:11 :
Ajout d'un zip d'exemple
09 août 2006 15:48:15 :
ajout de lstrlen
09 août 2006 17:52:06 :
mise en mémoire de la chaine de caractère
09 août 2006 17:54:34 :
bug résolu
09 août 2006 17:55:57 :
mise à jour
09 mars 2007 21:31:01 :
Changement du test de >0 à <>0
09 mars 2007 21:34:17 :
légère modif du texte

Commentaires et avis

signaler à un administrateur
Commentaire de bouv le 08/08/2006 21:53:05

Cela semble vraiment pas mal mais pourrais tu mettre un projet avec un exemple d'utilisation.

signaler à un administrateur
Commentaire de MadM@tt le 08/08/2006 23:40:51

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

signaler à un administrateur
Commentaire de Willi le 09/08/2006 09:11:32 administrateur CS

Bonne démo, les prochaines fois pense à déposer ce genre de code tout pret (snippet) sur www.codyx.org.

Bonne continuation ++

signaler à un administrateur
Commentaire de Renfield le 09/08/2006 09:45:45 administrateur CS

j'aime pas trop le coup du
Space(256)

lstrlen pourrait directement te filer la bonne taille a allouer

signaler à un administrateur
Commentaire de MadM@tt le 09/08/2006 15:52:58

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 ?

signaler à un administrateur
Commentaire de PCPT le 09/08/2006 16:37:17 administrateur CS

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

++ ;)

signaler à un administrateur
Commentaire de MadM@tt le 09/08/2006 16:48:23

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.

signaler à un administrateur
Commentaire de bouv le 09/08/2006 16:50:52

en faisant

Public Function GetStringFromPtr(ByRef Pointeur As String) As String

cela peut valoir le coup ^^

signaler à un administrateur
Commentaire de MadM@tt le 09/08/2006 17:31:36

ben je ne suis pas censé avoir la variable string, seulement son pointeur, sinon aucun intéret...
enfin c'était ptet ironique ? lol

signaler à un administrateur
Commentaire de bouv le 09/08/2006 17:37:17

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)?

signaler à un administrateur
Commentaire de bouv le 09/08/2006 17:41:19

PS : Comment se fait-il que tu n'ai que le pointeur de ta variable ?

signaler à un administrateur
Commentaire de MadM@tt le 09/08/2006 17:46:56

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.

signaler à un administrateur
Commentaire de MadM@tt le 09/08/2006 17:51:26

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

signaler à un administrateur
Commentaire de MadM@tt le 09/08/2006 17:53:56

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

signaler à un administrateur
Commentaire de bouv le 09/08/2006 19:52:29

TB, maintenant je peux noter.
10/10

signaler à un administrateur
Commentaire de Renfield le 09/03/2007 09:45:14 administrateur CS

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...

signaler à un administrateur
Commentaire de MadM@tt le 09/03/2007 20:47:48

ah ouais ? je savais pas, c'est mieux que j'enlève totalement le test ou je met <> 0 selon toi ?

signaler à un administrateur
Commentaire de Renfield le 09/03/2007 21:00:25 administrateur CS

<>0 fera l'affaire ^^

le signe, ca n'est qu'une question de représentation...

signaler à un administrateur
Commentaire de MadM@tt le 09/03/2007 21:31:36

Ok merci c'est fait ;)

signaler à un administrateur
Commentaire de BIGDAMSBIG le 13/01/2008 23:10:24



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





Ajouter un commentaire

Discussions en rapport avec ce code source dans le forum

tableau de chaine...subtile. [ par rurouni ] bon, je suis pas encore le pro du VB...donc je vous pose mon probleme...J ai declare un tableau de string comme ca:Dim tab_str(10) As String * 9pour a adresse mémoire d'une variable ou d'un objet [ par chrbard ] quel est le moyen en visaul basic pour connaitre l'adresse mémoire d'une variable ou d'un objet ?merci adresse mémoire [ par chrbard ] quel est le moyen ene visaul basic d'obtenir en cours d'execution de programme l'adresse mémoire d'une variable ou d'un objet ? merci Manipulation de chaine de caractères ... [ par ALBRECHOGAN ] Bonjour ...En fait, j'aurais voulu savoir comment m'y prendre pour manipuler des string (c ce que j'appelle chaine de caracteres) ...J'aurais en effet PRobleme dans une recherche de texte... [ par Clonk ] j'effectue une recherche dans un fichier texte pour récupérer 2 valeurs et les incorporer dans une base, mais j'ai un problème, voilà mon code:Private Chaine de caractere [ par Frank19 ] Jai une chaine de caractere du style :dim TextRecu1 as stringTcpclient.getdata (TextRecu1)...Le TextRecu1 est égale à MmessageCe que je veux faire, c' COMMENT LIRE UNE ADRESSE MéMOIRE D'UN PROGRAMME OUVERT ??? [ par TheBabyCool ] J'aimerai pouvoir lire une adresse mémoire d'un jeu ou d'un programme ouvert pour pouvoir, par exemple faire un trainer, ou tromper certain programme. COMMENT LIRE UNE ADRESSE MéMOIRE D'UN PROGRAMME OUVERT ??? [ par TheBabyCool ] J'aimerai pouvoir lire une adresse mémoire d'un jeu ou d'un programme ouvert pour pouvoir, par exemple faire un trainer, ou tromper certain programme. COMMENT LIRE UNE ADRESSE MéMOIRE D'UN PROGRAMME OUVERT ??? [ par TheBabyCool ] J'aimerai pouvoir lire une adresse mémoire d'un jeu ou d'un programme ouvert pour pouvoir, par exemple faire un trainer, ou tromper certain programme. COMMENT LIRE UNE ADRESSE MéMOIRE D'UN PROGRAMME OUVERT ??? [ par TheBabyCool ] J'aimerai pouvoir lire une adresse mémoire d'un jeu ou d'un programme ouvert pour pouvoir, par exemple faire un trainer, ou tromper certain programme.


Nos sponsors

Sondage...

CalendriCode

Septembre 2008
LMMJVSD
1234567
891011121314
15161718192021
22232425262728
2930     

Consulter la suite du CalendriCode

Téléchargements

Logiciels à télécharger sur le même thème :



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel BAÏSE, Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,45 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.