[VBA] Comment Verfier qu'un Pointeur est valide ?

RAFAAJ2000 Messages postés 16 Date d'inscription samedi 27 mars 2010 Statut Membre Dernière intervention 30 décembre 2012 - 29 déc. 2012 à 07:29
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 - 30 déc. 2012 à 08:13
Bj et joyeux Noel

Je cherche depuis des jours a savoir comment verifier si une variable Long contient un pointeur d'un object..... J'ai besoin de savoir ca avant de passer la variable a la fonction API CopyMemory car si la variable ne contient pas de pointeur valide l'application fait un crash et plante.

Pour illustrer le probleme considerant l'exemple suivant ( testé en Excel )

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
pDest As Any, pSrc As Any, ByVal ByteLen As Long)

Sub Test()

    Dim lPtr As Long
    Dim oTempObject As Object

    lPtr =   objPtr(Application)
    CopyMemory oTempObject, lPtr, 4
        MsgBox oTempObject.Name
    CopyMemory oTempObject, 0&, 4

End Sub


L'exemple ci-dessus fonctionne tres bien et le MsgBox returne le nom de l'application comme prevu.

Cependant, si la variable lPtr contient un pointeur invalide disant par example que lPtr = 1111 dans ce cas, le code plante.

Example qui plante l'application :

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
pDest As Any, pSrc As Any, ByVal ByteLen As Long)

Sub Test()

    Dim lPtr As Long
    Dim oTempObject As Object

    lPtr  = 1111 '<------ Pointeur invalide.
    CopyMemory oTempObject, lPtr, 4 ' <--------- CRASH ICI !!!!!
        MsgBox oTempObject.Name
    CopyMemory oTempObject, 0&, 4

End Sub


J'ai essayé les fonctions API IsBadReadPtr ;IsBadWritePtr et IsBadCodePtr mais sans aucun succés.

14 réponses

NHenry Messages postés 15113 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 22 avril 2024 159
29 déc. 2012 à 14:22
Bonjour,

En général, soit la fonction te retourne un pointeur valide, soit te retourne 0.

v----Signature--------v----------------------------------------------
[list=ordered][*]Pour poser correctement une question et optimiser vos chances d'obtenir des réponses, pensez à lire le règlement CS, celui-ci pour bien poser votre question ou encore celui-ci pour les PFE et autres exercices.[*]Quand vous postez un code, merci d'utiliser la coloration syntaxique (3ième icône en partant de la droite : ).[*]En VB.NET pensez à activer Option Explicit et Option Strict (propriété du projet) et à retirer l'import automatique de l'espace de nom Microsoft.VisualBasic (onglet Références dans les propriétés du projet).[*]Si votre problème est résolu (et uniquement si c'est le cas), pensez à mettre "Réponse acceptée" sur le ou les messages qui vous ont aidés/list
---
Mon site
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
29 déc. 2012 à 14:45
Bonjour, NHenry

Le problème est que la fonction en cause (CopyMemory) est l'une des rares fonctions de l'Api de Windows qui ne retourne RIEN (aucune valeur)
Le demandeur devrait par contre se demander si 1111 est un objet et si tel est le cas, comment on définit un objet ! Xe qui n'est pas le cas de :
lPtr = 1111

Il est assez grave, paradoxal et révélateur qu'il ne sache pas ce qu'est un Set (basique), mais se risque à l'utilisation de CopyMemory (complexe)
Ce sera donc ma seule intervention ici.
________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviendrai que si nécessité de la compléter.
0
RAFAAJ2000 Messages postés 16 Date d'inscription samedi 27 mars 2010 Statut Membre Dernière intervention 30 décembre 2012
29 déc. 2012 à 15:47
Merci

La raison pour la quelle je doit savoir au prealable si la variable contient un pointeur valide est d"eviter le Crash quand on execute le CopyMemory.

L'exemple que j'ai fournit est une simplification pour illustrer le probleme de facon claire et facile a comprendre... En realité ,Ce que je suis en train de faire est un peu plus compliqué : Je suis en train de scanner la memoire entiére d'un processus byte par byte dans une boucle jusqu'a ce que j'arrive au pointeur en cause et le stirer dans la variable object oTempObject .

J'espére toujours que quelqu'un connaissera une solution a ce probleme. Merci d'avance.
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
29 déc. 2012 à 19:10
jusqu'a ce que j'arrive au pointeur en cause et le stirer dans la variable object oTempObject

Autant tu peux connaître l'adresse d'une variable objet (que te retourne objptr), autant tu ne peux, à partir d'une adresse en mémoire, déterminer l'objet qu'elle concerne. Ces choses-là sont gérées par VB, qui procède ainsi pour ses propres applis :
- attribution d'une adresse, sur laquelle il travaille ensuite
- pour s'y retrouver, il associe d'emblée chaque variable à une adresse. S'il ne connait pas cette association, il ne peut rien faire.
C'est également la raison pour laquelle, entre autres, on ne peut dans VB se référer à une variable à partir de la chaîne de caractères qui la nomme.

________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviendrai que si nécessité de la compléter.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
RAFAAJ2000 Messages postés 16 Date d'inscription samedi 27 mars 2010 Statut Membre Dernière intervention 30 décembre 2012
29 déc. 2012 à 20:34
autant tu ne peux, à partir d'une adresse en mémoire, déterminer l'objet qu'elle concerne


Si on peut , à partir d'une adresse en mémoire, déterminer l'objet qu'elle concerne c'est ce que je viens de faire dans mon code grace a la fonction CopyMemory
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
29 déc. 2012 à 21:09
En VB6 ?
Montre donc !


________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviendrai que si nécessité de la compléter.
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
29 déc. 2012 à 21:18
Je ne saurais le jurer, mais mon petit doigt me dit que tu travailles sous VBA et non sous VB6 !


________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviendrai que si nécessité de la compléter.
0
RAFAAJ2000 Messages postés 16 Date d'inscription samedi 27 mars 2010 Statut Membre Dernière intervention 30 décembre 2012
29 déc. 2012 à 22:07
Je ne saurais le jurer, mais mon petit doigt me dit que tu travailles sous VBA et non sous VB6


Oui c'est vrai je travaille sur VBA mais c'est la meme chose sur VB6.

à partir d'une adresse en mémoire,on peut bien déterminer l'objet qu'elle concerne grace a la fonction CopyMemory ... Voici le code :

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
pDest As Any, pSrc As Any, ByVal ByteLen As Long)

Sub Test()

    Dim lPtr As Long
    Dim oTempObject As Object

    lPtr = objPtr(Application)
    CopyMemory oTempObject, lPtr, 4
        MsgBox oTempObject.Name
    CopyMemory oTempObject, 0&, 4

End Sub
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
29 déc. 2012 à 22:21
Oui c'est vrai je travaille sur VBA

1Alors bye bye, ami ! Car tout le reste risque d'être aussi précis que lke choix que tu as fait de la section où ouvrir cette discussion.


________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviendrai que si nécessité de la compléter.
0
RAFAAJ2000 Messages postés 16 Date d'inscription samedi 27 mars 2010 Statut Membre Dernière intervention 30 décembre 2012
29 déc. 2012 à 23:26
Les APIs fonctionnent de facon identique que ce soit en VB6 ou en VBA .... Le probleme que je decris ici se passe aussi bien en VB6 qu'on VBA.
0
Utilisateur anonyme
30 déc. 2012 à 02:40
Bonjour,

Dès que tu vas tomber avec un Office à 64 bits, ton programme va planter. Avec 64 bits, tous les programmes VBA qui utilisent des fonctions API qui font appel à des pointeurs ou à des handles, plantent ou donnent des résultats erronnés. Donc, si tant est que tu récupères bien le nom d'un objet, il se pourrait bien que ce ne soit pas le bon objet.

Va voir là,
et
0
RAFAAJ2000 Messages postés 16 Date d'inscription samedi 27 mars 2010 Statut Membre Dernière intervention 30 décembre 2012
30 déc. 2012 à 02:53
Dès que tu vas tomber avec un Office à 64 bits, ton programme va planter. Avec 64 bits, tous les programmes VBA qui utilisent des fonctions API qui font appel à des pointeurs ou à des handles, plantent ou donnent des résultats erronnés


Non, c'est pas correct ... avec office 64 bits il faut simplement changer légerement les declarations des APIs et le reste du programme fonctionne bien.
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
30 déc. 2012 à 08:06
Réflexe à avoir :
Sous VB6 (hein !)
1) un projet avec un Form , une picturebox, un bouton de commande et une textbox
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
pDest As Any, pSrc As Any, ByVal ByteLen As Long)

Sub Test()

    Dim lPtr As Long
    Dim oTempObject As Object

    lPtr = ObjPtr(Me.Picture1)
    CopyMemory oTempObject, lPtr, 25
        MsgBox oTempObject.Name
        Text1.Text = lPtr
    CopyMemory oTempObject, 0&, 25

End Sub



Private Sub Command1_Click()
 Test
End Sub

On lance ===>> parfait (une messagebox disant bien Picture1)

2) on laisse ouverte l'appli 1 (celle ci-dessus)
et on fait un second projet, auquel on basse maintenant la valeur (copié/collé de la textbox du 1er projet) de lptr ===>> Bonjour les dégâts ==> sans commentaire. Je te laisse tirer tes conclusions


________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviendrai que si nécessité de la compléter.
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
30 déc. 2012 à 08:13
en te rappelant ce que tu as dit plus haut :
Je suis en train de scanner la memoire entiére d'un processus byte par byte dans une boucle jusqu'a ce que j'arrive au pointeur en cause et le stirer dans la variable object oTempObject .

Car j'imagine que le "processus" examiné n'est pas le tien (sinon : aucun intérêt)



________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviendrai que si nécessité de la compléter.
0
Rejoignez-nous