Utiliser des pointeurs mémoires comme réf pour un sous-prog

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Octavius
Messages : 312
Inscription : jeu. 26/juil./2007 12:10

Utiliser des pointeurs mémoires comme réf pour un sous-prog

Message par Octavius »

Bon je me risque à poster ce petit bout de code parce que je n'ai trouvé aucun tutoriel qui expliquait ça. Je l'ai trouvé tout seul (alors j'espère ne pas avoir l'air bête de celui qui redécouvre la roue! :oops: ), il est possible d'utiliser l'adresse mémoire d'un label pour faire appel à un sous-programme grâce à CallFunctionFast, et revenir au programme principal avec Return exactement comme avec Gosub. Exemple :

Code : Tout sélectionner

*Prog=?Prog

Resultat=CallFunctionFast(*Prog)

Print("Fin")
Delay(1000)
End

Prog:

OpenConsole()
PrintN("Debut")
Delay(1000)

Return
Bon, vous allez me dire, mais quel est l'intérêt ??? Je pense que ce genre d'astuce peut être utile quand on a un grand nombre de sous-programmes, ça permet de les stocker facilement dans une liste chaînée par exemple. Je pense notamment à ceux qui s'amuse à bidouiller des langages de programmation interprété, personnellement ça m'a bien débloqué de trouver ça. La seule question que je me pose c'est s'il est possible de retourner un résultat dans Resultat ?
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

Je pige pas tout la

Pourquoi tu ne fais pas des Procedure ?
Octavius
Messages : 312
Inscription : jeu. 26/juil./2007 12:10

Message par Octavius »

Les sous-programmes sont plus rapides si on n'a pas besoin de la propriété récursive des procédures (une procédure peut s'appeller elle-même). Je trouve aussi que ça clarifie le programme quand on s'oblige à ne jamais faire de fonctions récursives.
poshu
Messages : 1138
Inscription : sam. 31/juil./2004 22:32

Message par poshu »

hmmm, en effet, je ne savais pas qu'on pouvait faire ca, mais je rejoind LCI: une procédure, c'est plus claire et je suis rarement à 3hz près sur mes programmes
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

c'est etonnant de pouvoir faire cela :)

mais je reste avec mes Gosub tant qu'a faire :)
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Message par Kwai chang caine »

Ce qui serait bien, c'est de pouvoir insérer une procedure dans une procedure.
Ou bien un gosub return dans une procedure.

Car parfois y'a des codes qui nécéssitent deux procedures qui sont liées ensembles.
Et donc ça sert à rien de créer deux procedure, sauf à oublier d'en copier une des deux ou trois et d'avoir un gros message d'erreur comme quoi cette instruction n'est ni un tableau ni une fonction :?

Comme par example dans ce code qui est génial, dont j'avais besoin et que m'a donné SROD, pour compter les gadgets par type dans une fenetre .
Mais bon la procedure est constituée de 2 procédures + 1 declaration.
Bon on peut mettre la declaration dans la procedure, je l'ai déja fait plusieur fois et ça marche, mais on ne peut pas merger les deux :?

Et je trouve ça dommage, pour la clarté d'un code.
Apres tout si elle ne sert qu'a cette instruction pourquoi ne pas pouvoir la mettre dedans :?
Reste encore les PBI équivalents des modules VB ou l'on mettrait que ce code, soit, mais ça fait plein de petits fichiers qui tourne autour de l'appli principale, encore un moyen d'en oublier un ....

Code : Tout sélectionner

Structure _countgadgets 
  className$ 
  count.l 
EndStructure 

Procedure.l EnumChildWindowProc(hwnd, *cg._countgadgets) 
  Protected buffer$ 
  buffer$=Space(100) 
  GetClassName_(hwnd, @buffer$, 100) 
  If buffer$ = *cg\className$ 
    *cg\count + 1 
  EndIf 
  ProcedureReturn 1 
EndProcedure 


;The following function takes a window handle and a gadget handle and returns a count of the 
;number of similar controls on the given window. 
;This count includes the specified gadget. 
Procedure.l CountSimilarGadgets(winhWnd, gadgethWnd) 
  Protected buffer$ 
  Protected cg._countgadgets 
  If IsWindow_(winhWnd) And IsWindow_(gadgethWnd) 
    buffer$=Space(100) 
    GetClassName_(gadgethWnd, @buffer$, 100) 
    cg\className$ = buffer$ 
    EnumChildWindows_(winhWnd, @EnumChildWindowProc(),@cg) 
  EndIf 
  ProcedureReturn cg\count 
EndProcedure 


If OpenWindow(0, 100, 100, 600, 600, "Count gadgets", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0)) 
  ButtonGadget(0, 10, 10, 200, 20, "Standard Button") 
  ButtonGadget(1, 10, 40, 200, 20, "Left Button", #PB_Button_Left) 
  ButtonGadget(2, 10, 70, 200, 20, "Right Button", #PB_Button_Right) 
  ButtonGadget(3, 10,100, 200, 60, "Multiline Button  (longer text gets automatically wrapped)", #PB_Button_MultiLine) 
  ButtonGadget(4, 10,170, 200, 20, "Toggle Button", #PB_Button_Toggle) 
  count = CountSimilarGadgets(WindowID(0), GadgetID(0)) 
  Debug "There are " + Str(count) + " buttons!" 

  Repeat 
    event = WaitWindowEvent() 
  Until event = #PB_Event_CloseWindow 
EndIf 
End 

tmyke
Messages : 1554
Inscription : lun. 24/juil./2006 6:44
Localisation : vosges (France) 47°54'39.06"N 6°20'06.39"E

Re: Utiliser des pointeurs mémoires comme réf pour un sous-p

Message par tmyke »

Octavius a écrit : .. La seule question que je me pose c'est s'il est possible de retourner un résultat dans Resultat ?
Tu peux plutôt ecrire ce genre de code, pour un resultat similaire, que je pense plus propre
en terme de codage, tout en gardant l'espris de ce que tu as déjà écris et qui te permet en plus d'avoir
des valeurs de retour...

Code : Tout sélectionner

Declare Prog()

*ProgPtr = @Prog()
Resultat=CallFunctionFast(*ProgPtr)

Debug("Fin")
Delay(1000)
Debug Resultat
End

Procedure Prog()
  Debug "Debut"
  Delay(1000)
  ProcedureReturn 12
EndProcedure
Force et sagesse...
Répondre