Page 2 sur 2

Publié : lun. 17/juil./2006 21:22
par nico
Les pointeurs sont justes les éléments les plus importants en prog, on ne peut pas s'en passer, et surtout on n'est souvent obligé de les utiliser pour exploiter les fenêtres Windows et gadgets avec des CallBack. Ils apportent une grande souplesse de programmation car avec un pointeur on peut passer un nombre illimité d'arguments et jouer avec toutes variables en mémoire.

Publié : mar. 18/juil./2006 0:17
par Flype
un petit example d'utilisation de pointeurs pour wolfjeremy:

pour example, je choisis de montrer comment une procédure
peut renvoyer plusieurs valeurs d'un coup.
Un seul ProcedureReturn donc, pour plusieurs valeurs retournées.

un pointeur n'a besoin d'avoir une étoile pour se comporter
comme un pointeur. mais son utilisation va en être limitée !

regarde ici comment on aurait fait sans connaitre les structures :

1/
allocation d'un bloc de mémoire de la taille de tous les arguments
taille = 1 octet (.b) + 4 octets (.l) + 4 octets (.s) = 9 octets
args.l est donc le pointeur sur un bloc mémoire

2/
on 'poke' la mémoire avec nos valeurs

3/
et on la 'peek'

4/
on libère la mémoire allouée

Code : Tout sélectionner

Procedure.l MaProcedure_Alloc()
  
  Protected args.l = AllocateMemory(1+4+4)
  
  If args
    PokeB(args+0, #True)
    PokeL(args+1, 123)
    PokeS(args+5, "456")
  EndIf
  
  ProcedureReturn args
  
EndProcedure

Procedure.l MaProcedure_Free(args)
  
  If args
    FreeMemory(args)
  EndIf
  
EndProcedure

a.l = MaProcedure_Alloc()

If a
  
  Debug PeekB(a+0)
  Debug PeekL(a+1)
  Debug PeekS(a+5)
  
  MaProcedure_Free(a)

EndIf
bon, çà c'était avant...

en rajoutant maintenant l'étoile devant notre pointeur on peut lui coller une structure derrière (hum).

args devient *args.ARGUMENTS

ainsi PokeL(args+1, 123) devient *args\lValeur = 123

avec les structures c'est plus de code mais c'est surtout plus lisible, plus souple.

Code : Tout sélectionner

Structure ARGUMENTS
  bValeur.b
  lValeur.l
  sValeur.s
EndStructure

Procedure.l MaProcedure_Alloc()
  
  Protected *args.ARGUMENTS = AllocateMemory(SizeOf(ARGUMENTS))
  
  If *args
    *args\bValeur = #True
    *args\lValeur = 123
    *args\sValeur = "456"
  EndIf
  
  ProcedureReturn *args
  
EndProcedure

Procedure.l MaProcedure_Free(*args.ARGUMENTS)
  
  If *args
    FreeMemory(*args)
  EndIf
  
EndProcedure

*a.ARGUMENTS = MaProcedure_Alloc()

If *a
  
  Debug *a\bValeur
  Debug *a\lValeur
  Debug *a\sValeur
    
  MaProcedure_Free(*a)

EndIf

Publié : mar. 18/juil./2006 9:52
par wolfjeremy
Ouai merci pour l'exemple, il est très clair ! :P

Flype tu m'aura déjà aider beaucoup quand même :D

Encore merci.

Publié : mar. 18/juil./2006 10:12
par comtois
Petite question qui me traverse l'esprit en voyant ton exemple Flype

Code : Tout sélectionner

FreeMemory(args)

ok ça libère les 9 octets alloués avec AllocateMemory, mais un champ était un pointeur vers une chaîne, comment on libère l'espace occupé par une chaîne ?

Faudrait que je fasse des recherches, il me semble avoir déjà vu des débats à ce sujet ici ou sur le forum anglais.

Publié : mar. 18/juil./2006 10:56
par wolfjeremy
J'ai aussi une question.

Où trouve où toute les fonctions qui sont en rapport avec les pointeurs dans la doc de PB ? Ces éparpiller un peu partout dans chaque catégorie ? ( 8O )

Publié : mar. 18/juil./2006 13:22
par Flype
c'est normal qu'ils sont éparpiller un peu partout.

comme le dit si bien nico :
nico a écrit :Les pointeurs sont justes les éléments les plus importants en prog, on ne peut pas s'en passer, et surtout on n'est souvent obligé de les utiliser pour exploiter les fenêtres Windows et gadgets avec des CallBack. Ils apportent une grande souplesse de programmation car avec un pointeur on peut passer un nombre illimité d'arguments et jouer avec toutes variables en mémoire.

Publié : mar. 18/juil./2006 13:28
par Flype
comtois a écrit :Petite question qui me traverse l'esprit en voyant ton exemple Flype

Code : Tout sélectionner

FreeMemory(args)

ok ça libère les 9 octets alloués avec AllocateMemory, mais un champ était un pointeur vers une chaîne, comment on libère l'espace occupé par une chaîne ?

Faudrait que je fasse des recherches, il me semble avoir déjà vu des débats à ce sujet ici ou sur le forum anglais.
-----------

à mon avis - pas de problème ici.

Si on fait PokeL(args+5, @"456")

"456" est une chaine allouée en dur dans le programme / dans l'exécutable. pas besoin de la libérer.

Imagine, çà reviendrait à chercher à faire FreeMemory(@"456")
ce que je conseille à personne.

-----------

Si on fait :

maChaine.s = "test"
PokeL(args+5, @maChaine)
FreeMemory(args)

La chaine est toujours allouée meme après le FreeMemory puisque la variable maChaine n'est pas détruite (heureusement).

La chaine sera libérée par purebasic en sortant de la procédure (EndProcedure) ou du programme (End).

Publié : mar. 18/juil./2006 13:48
par Flype
Pas bien Flype :evil:

Il y a quand même une grossière erreur dans mon premier example.

Voilà la correction, je vous laisse deviner où et pourquoi :wink:

Code : Tout sélectionner

Procedure.l MaProcedure_Alloc() 
  
  Protected args.l = AllocateMemory(1+4+4) 
  
  If args 
    PokeB(args+0, #True) 
    PokeL(args+1, 123) 
    PokeL(args+5, @"456") 
  EndIf 
  
  ProcedureReturn args 
  
EndProcedure 

Procedure.l MaProcedure_Free(args) 
  
  If args 
    FreeMemory(args) 
  EndIf 
  
EndProcedure 

a.l = MaProcedure_Alloc() 

If a 
  
  Debug PeekB(a+0) 
  Debug PeekL(a+1) 
  Debug PeekS(PeekL(a+5))
  
  MaProcedure_Free(a) 

EndIf

Publié : mar. 18/juil./2006 14:17
par wolfjeremy
Le PokeS lol

Publié : mar. 18/juil./2006 14:45
par Flype
oui mais pourquoi ?
c'est intéressant justement pour comprendre.

Quelle différence entre ces 2 là ?
PokeS(args+5, "456")
PokeL(args+5, @"456")

1 piste : l'écrasement mémoire...

Publié : mar. 18/juil./2006 15:07
par comtois
merci Flype, ça me semble logique en effet ; il me passe des trucs bizarres par la tête des fois :)