Pointeur en VB...

jockos Messages postés 321 Date d'inscription dimanche 22 octobre 2000 Statut Membre Dernière intervention 14 mai 2005 - 12 avril 2003 à 13:24
ofeelfree Messages postés 9 Date d'inscription mercredi 24 septembre 2003 Statut Membre Dernière intervention 14 juin 2005 - 19 févr. 2004 à 11:45
Ma question est simple...

Soit une variable 'strContenu1' de type String, contenant une très grosse chaine de caractère (un fichier texte de quelques Mo)...

J'ai une autre String 'strContenu2' et je voudrais que strContenu2 pointe sur la zone mémoire de strContenu1 pour ne pas recopier ma grosse chaine en mémoire...

Parce que l'instruction :

strContenu2 = strContenu1

recopie la chaine dans un autre emplacement de la mémoire vive (affectation)...

J'arrive à récupérer l'adresse mémoire de strContenu1 avec l'instruction suivante :

Dim pointeur as Long

pointeur = StrPtr(strContenu1)

Maintenant, il faut que je fasse "pointer" strContenu2 sur cette zone mémoire...
Il doit y avoir une API...

Mais laquelle... je cherche désespérement depuis hier...

Cela permettrait d'optimiser la performance des programmes VB... optimiser la consommation en mémoire vive...

Merci pour votre aide...

16 réponses

cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
12 avril 2003 à 14:59
Oui en effet, il existe l'API CopyMemory qui permet de copier le contenu de la mémoire à une adresse donnée.

Pour plus d'info sur cette API, va voir dans la bibliothèque d'API du site www.ProgOtoP.com

DARK SIDIOUS

[Responsable de la rubrique API du site www.ProgOtoP.net]
0
jockos Messages postés 321 Date d'inscription dimanche 22 octobre 2000 Statut Membre Dernière intervention 14 mai 2005 2
12 avril 2003 à 15:11
CopyMemory permet de copier un contenu mémoire vers un autre emplacement de la mémoire.
C'est l'API qui doit être utilisé pour la définition de l'opérateur d'affectation '=' du langage VB.

C'est justement ce que je veux pas faire...

Je veux que mes 2 variables pointes sur le même emplacement mémoire...
Qu'elles se le partagent si tu préfères...

Je veux donc être capable de faire pointer plusieurs variables VB sur un même emplacement mémoire...

Or l'API CopyMémory ne permet pas de faire cela...

Merci quand même pour ton aide...
0
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
12 avril 2003 à 15:59
Donc en gros, tu veux uniquement copier le contenu de l'adresse mémoire ?

Si c'est cà, il te suffit de copier le contenu du pointeur, non ?

DARK SIDIOUS

[Responsable de la rubrique API du site www.ProgOtoP.net]
0
jockos Messages postés 321 Date d'inscription dimanche 22 octobre 2000 Statut Membre Dernière intervention 14 mai 2005 2
12 avril 2003 à 16:57
Exactement...

Mais comment faire pointer une variable VB sur une Zone mémoire déjà alloué...
Il y a 2 choses à préciser :
- l'adresse mémoire du début de la données
- sa longueur (offset)

Et éventuellement son type de données pour l'interprétation du contenu...

Si ma données fais 3 Méga octets, je ne veu xpas qu'elle soit ptésente à 2 endroits différents de la mémoire...
Mais je veux que cette données soit accessible depuis 2 variables VB...

Les pointeurs en C, C++ et dans tous les langages évolués et fortement typé servent entre autre à cela...
Avec VB, on ne peux pas accéder de la sorte à la mémoire, aussi facilement qu'en C... Mais je suis sûr qu'avec les API, on doit pouvoir faire des choses performantes...

Donc mon problème revient à faire pointer plusieurs variables VB sur une zone mémoire (identitifié par son adresse de début et sa longueur en octet).

Rien de bien compliqué dans le concept,mais alors pour le mettre en pratique en VB, c'est vraiment la galère.

Tu comprends mieux ce que je veux faire exactement ou ne suis-je toujours pas assez précis dans ma demande ?
0

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

Posez votre question
stevebelgium Messages postés 180 Date d'inscription lundi 17 mars 2003 Statut Membre Dernière intervention 7 juin 2003 1
12 avril 2003 à 18:01
I'm going to give a try ; don't shoot me !

Private Sub Command1_Click()

Dim strContenu1 As String

strContenu1 = "aaa"

test strContenu1


End Sub

Sub test(ByRef strContenu2 As String)

' NOT byVal

MsgBox strContenu2

'pointer strContenu2 same as strContenu1

End Sub
0
jockos Messages postés 321 Date d'inscription dimanche 22 octobre 2000 Statut Membre Dernière intervention 14 mai 2005 2
12 avril 2003 à 18:30
Je connais la différence entre ByVal et ByRef au niveau des passages de paramètres dans une fonction VB...
Et ça ne répond pas à mon problème, car tu n'a pas déclaré une 2ème variable strContenu2. C'est le paramètre...
Et comme il est passé par référence ByRef(on dit aussi par adresse), on accède bien au même contenu mémoire...

JE suis Ok avec cela, mais par contre, comme je le dis, ça ne répond pas à mon problème, car tu n'as pas déclaré une véritable 2ème variable différente...

Je voudrais un truc du genre :

**********************
Dim strContenu1 As String
Dim pointeur As Long
Dim strContenu2 As String

strContenu1 = "123fdjhjjjkn,gdfsnlkjhkdshlk"

'Récupère l'adresse du bloc mémoire de strContenu1
pointeur = StrPtr(strContenu1)

FaitPointer(strContenu2,pointeur,len(strContenu1))

Je veux que la fonction 'FaitPointer' fasse pointer strContenu2 sur la zone mémoire contenant la variable strContenu1.

Ainsi, ces 2 variables se partage la même zone mémoire.

Si strContenu1 est modifié, alors strContenu2 est modifié...

C'est EXACTEMENT la notion de pointeurs, très utilisé en C, C++ ....... et très très pratique au niveau performance...

Mais en VB.... :( ........ j'commence à baisser les bras....
0
stevebelgium Messages postés 180 Date d'inscription lundi 17 mars 2003 Statut Membre Dernière intervention 7 juin 2003 1
12 avril 2003 à 18:59
Here is your answer !

just copy paste into a project

Option Explicit

Private Declare Sub CopyMemory Lib "kernel32" _
Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Function GetProcessHeap Lib "kernel32" () As Long
Private Declare Function HeapAlloc Lib "kernel32" _
(ByVal hHeap As Long, ByVal dwFlags As Long, ByVal dwBytes As Long) As Long
Private Declare Function HeapFree Lib "kernel32" _
(ByVal hHeap As Long, ByVal dwFlags As Long, lpMem As Any) As Long
Private Declare Sub CopyMemoryWrite Lib "kernel32" Alias _
"RtlMoveMemory" (ByVal Destination As Long, Source As Any, ByVal Length As Long)
Private Declare Sub CopyMemoryRead Lib "kernel32" Alias _
"RtlMoveMemory" (Destination As Any, ByVal Source As Long, ByVal Length As Long)

Private Sub Form_Load()
Dim ptr As Long 'int * ptr;
Dim hHeap As Long
hHeap = GetProcessHeap()
ptr = HeapAlloc(hHeap, 0, 2) 'an integer in Visual Basic is 2 bytes
If ptr <> 0 Then
'memory was allocated
'do stuff
Dim i As Integer
i = 12
CopyMemoryWrite ptr, i, 2 ' an intger is two bytes
Dim j As Integer
CopyMemoryRead j, ptr, 2
MsgBox "The adress of ptr is " & CStr(ptr) & _
vbCrLf & "and the value is " & CStr(j)
HeapFree GetProcessHeap(), 0, ptr

MsgBox i & " " & j
End If
End Sub
0
stevebelgium Messages postés 180 Date d'inscription lundi 17 mars 2003 Statut Membre Dernière intervention 7 juin 2003 1
12 avril 2003 à 19:20
0
jockos Messages postés 321 Date d'inscription dimanche 22 octobre 2000 Statut Membre Dernière intervention 14 mai 2005 2
13 avril 2003 à 14:41
Désolé d'être exigent... mais c'est toujours pas cela...
Tes propositions sont très bonnes et c'est vraiment sympa d'essayer de trouver la solution, mais ça ne marche toujours pas...

CopyMemoryRead va lire la valeur qui se trouve à une certaine adresse mémoire et la copie dasn une variable de destinataion ( j dans l'exemple de code).

la variable i et j ne pointe donc pas sur la même zone mémoire...

pour tester, il te suffit de faire à la fin de ton code :

i = 20

Msgbox Cstr(i)+" "+cstr(j)

Et là, tu remarques que j ne vaut pas 20... il ne pointe donc pas sur la même zone mémoire que la variable i (car sinon, il vaudrait aussi 20).

Bien essayé en tous cas... mais il faut laisser tomber l'API CopyMemory, car je ne veux surtout pas copier une zone mémoire, je veux simplement partagé une seule et unique zone mémoire pour plusieurs variables . (on dit qu'elles pointent sur cette emplacement mémoire).

Dur dur en VB......... :(
0
cs_snook Messages postés 13 Date d'inscription vendredi 10 janvier 2003 Statut Membre Dernière intervention 24 juillet 2003
5 juin 2003 à 15:44
as-tu trouver une solution a ton pb car ca m'interesse moi aussi!

Daniel
0
jockos Messages postés 321 Date d'inscription dimanche 22 octobre 2000 Statut Membre Dernière intervention 14 mai 2005 2
5 juin 2003 à 16:20
Hélas non...
Et pourtant, j'ai beaucoup cherché...

Il faut se résoudre à l'évidence, le VB ne permet pas de gérer une même zone mémoire avec plusieurs varaibles. (pointeurs contenant l'adresse mémoire de cette zone).

Si tu veux optimiser la gestion mémoire, il faut changer de langage...
Moi, je vais faire migrer mon appli en Delphi...
Excellent RAD (style VB) et langage très puissant (Pascal Objet).

Bon courage...
0
cs_snook Messages postés 13 Date d'inscription vendredi 10 janvier 2003 Statut Membre Dernière intervention 24 juillet 2003
5 juin 2003 à 16:37
oui, c'est vraiment dommage que VB ne gère pas
cela.
Pour y remedier partiellement, j'implémente souvent
certaine routine dans des DLL en C, mais j'ai tout de
meme des limitations:
Par exemple, imagine un processus assez long, il est interessant d'afficher une barre de progression.
Le processus peut tres bien etre dans la DLL en C mais
comment modifier la valeur de la progessbar... je ne sais pas s'il est possible de passer en argument un controle VB
dans une fonction d'une DLL en C.

En fait à ce stade, tu as certainement trouver la reponse: changer de langage...

Daniel
0
jockos Messages postés 321 Date d'inscription dimanche 22 octobre 2000 Statut Membre Dernière intervention 14 mai 2005 2
5 juin 2003 à 16:58
Il faut simplement que tu appelles ta procédure ou ta fonction C depuis l'évenement d'un Controle TIMER.
Ainsi, toutes les 300 ms par exemple, tu récupères la valeur que te retourne ta routine C et tu met à jour ta progressBar avec cette valeur...

Il y a certainement d'autre méthode possible...

En tous cas, en ce qui concerne les pointeurs et donc la gestion mémoire, je crois qu'on est d'accord sur le fait que VB n'est pas un bon langage la dessus...
Il est d'ailleur réputé pour sa lenteur d'exécution en mémoire et la lourdeur du code machine généré par le compilateur.

Par contre, il a évidemment des avantages non négligeable et je ne dis pas que VB est un langage pourri ou pour les débutant... loin de là, car on peut aller très loin en utilisant les API Windows...

Et c'est vrai que mélanger des routines "critiques" écrite en C (dans des dll ou éventuellement dans un ActiveX) avec du code VB semble être une très bonne alternative aux faiblesses de VB...

Que penses-tu de Delphi ?
0
cs_snook Messages postés 13 Date d'inscription vendredi 10 janvier 2003 Statut Membre Dernière intervention 24 juillet 2003
5 juin 2003 à 17:33
je ne connais pas du tout Delphi, uniquement le C et VB.
Chaqu'un a ces atouts et faiblesses, j'imagine que pour
Delphi c'est la meme chose?!

Et que dire de VB.net, le passage de VB6 a .net n'est
pas évident et vue les limitations de VB, je me demande
si ce n'est pas plus interessent de migrer les appli en C/C++,
au moins mis a part les appels d'API, le code est multiplateforme.
0
soleildz Messages postés 58 Date d'inscription dimanche 19 avril 2009 Statut Membre Dernière intervention 10 février 2016
22 déc. 2003 à 11:17
vb6 est "naturellement" lent ?
0
ofeelfree Messages postés 9 Date d'inscription mercredi 24 septembre 2003 Statut Membre Dernière intervention 14 juin 2005
19 févr. 2004 à 11:45
Salut,

Voici ce dont je me souviens de mes premiers pas en POO sous VB : les types objet ont un comportement par référence. Exemple :

Public Class MyObject

Public x as Integer

End Class

Public Module Test

Dim o1 As New MyObject()
o1.x = 6
Dim o2 As MyObject = o1

'Doit renvoyer 6 6
Console.WriteLine(o1.x & " " & o2.x)

o1.x = 12
'Doit renvoyer 12 12
Console.WriteLine(o1.x & " " & o2.x)

o2.x = 16
'Doit renvoyer 16 16
Console.WriteLine(o1.x & " " & o2.x)

Dim o3 as MyObject = CType(o1.Clone(), MyObject)
'Doit renvoyer 16 16
Console.WriteLine(o1.x & " " & o3.x)

o3.x = 4
'Doit renvoyer 16 4
Console.WriteLine(o1.x & " " & o3.x)

o2 = Nothing
'Doit renvoyer une erreur de non référence à une instance d'un objet
Console.WriteLine(o1.x)

End Module

Voila, j'espère que ça peut être une solution.
0
Rejoignez-nous