begin process at 2012 02 17 03:20:05
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

API

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

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


 Information sur la source

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

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
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é :10 144 / 556

Auteur : MadM@tt

Ecrire un message privé
Site perso
Ce membre participe au partage de revenus publicitaires
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

Les Membres Club peuvent 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

 Sources du même auteur

Source avec Zip COMMUNICATION INTER-PROCESSUS (IPC)
Source avec Zip OPÉRATIONS SUR LES CHAINES DE CARACTÈRE OPTIMISÉES ET ÉTENDU...
Source avec Zip Source avec une capture FISHTANK - SCREENSAVER INTERACTIF : AQUARIUM AVEC POISSONS V...
Source avec Zip Source avec une capture RÉCUPÉRER LA TEMPÉRATURE DES DISQUES DURS
Source avec Zip Source avec une capture WIN++ OPTIONS AVANCÉES SUR LES FENETRES ET PROCESSUS WINDOWS...

 Sources de la même categorie

Source avec Zip Source .NET (Dotnet) .NET DEPENDENCY VIEWER : ARBRE DES DÉPENDANCES D'UN ASSEMBLY... par ShareVB
Source avec Zip Source .NET (Dotnet) UTILITAIRE SKYDRIVE par MasterShadows
Source avec Zip ROTATION RAPIDE D'IMAGE par trex70
Source avec Zip Source avec une capture ENUMERATION DES PORTS TCP ET IDENTIFCATION DU PROCESS (PID) ... par Renfield
Source avec Zip Source avec une capture MOUSE SPEED AND WEIGHT : RETOUR DE FORCE VIRTUEL ! par ScSami

 Sources en rapport avec celle ci

Source avec Zip Source avec une capture Source .NET (Dotnet) JEU DE MÉMOIRE CLASSIQUE par raffika
Source .NET (Dotnet) UTILISATION DE SORTEDLIST POUR TRIER UNE COLLECTION DE VALEU... par blq
CHAÎNE ALÉATOIRE / RANDOM STRING par mizoz
Source avec Zip Source avec une capture Source .NET (Dotnet) CRYPTAGE ET DÉCRYPAGE D'UNE CHAÎNE DE CARACTÈRES par johann36
EXTRAIT UNE CHAINE ET SE QUI SUIT D'UNE AUTRE CHAINE (SANS L... par ols

Commentaires et avis

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.

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

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

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

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 ?

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

++ ;)

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.

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

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

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

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 ?

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.

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

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

Commentaire de bouv le 09/08/2006 19:52:29

TB, maintenant je peux noter.
10/10

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

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 ?

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

Commentaire de MadM@tt le 09/03/2007 21:31:36

Ok merci c'est fait ;)

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

GlobalAlloc et le partage d'adresse mémoire [ par jack ] Salut à tou(te)s Je n'ai déjà pas beaucoup de cheveux, mais là, j'arrive encore à me les arracher. J'ai une chaine à transmettre entre deux applicati Besoin Aide Concaténation en VB ?? [ par nico8001 ] Bonjour, j'ai un probleme pour mon projet en visual basic 2008 enfaite j'ai une base de données access 2000 avec 4 champs ( N°Machine , NomMachine erreur lors de l'xecution de mon programme [ par tif27940 ] Bonjour, voici mon programme : [code=aspx] Dim nom As String Dim pnom As String Dim civ As String Dim tel As String D Presence d'un caractere parmi une serie dans une chaine string [ par PeD ] Existe t il une fonction qui permette de savoir si une chaine contient un des caractères spécifiés dans l'argument de recherche. Certains langages ( P Commen changer un pointeur(long) en string? [ par JSilvere ] Bonjour, j'utilise une Dll qui me renvoi un pointeur, et j'aimerais le traduire en string afin de savoir à quoi cela correspond... Donc si quelqu'un garder mémoire un textbox [ par sancho12345 ] Bonsoir à tous, Comment peux ton faire pour garder mémoire un textbox. Exemple : Lorsque j’ouvre VB 6 j’aimerais que le texte que j’ai tapé dans le Comment implémenter en une seule fois une variable String [ par FunMagic ] Bonjour à tous, Je me creuse la tête car j'ai un soucis d'ordre général avec l'accès à des données. En résumer, j'ai un programme qui doit faire cert [déplacé VB.NET -> VBA] Soucis dans l'emploi d'une string en argument [ par NoEnclumeSVP ] Salut, Je dois développer une macro Excel qui doit aller chercher dans une feuille une liste d'entités (des clients) qui serviront dans une autre feu fonction [ par parkerandrea ] slt à tous je voudrais savoir comment appelé une fonction dans une form enplus qui peut m'aide a savoir ce ki ne va sur ce code ca ne marche chez et


Nos sponsors


Sondage...

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), 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

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 2,090 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales