Page 1 sur 1

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

Publié : jeu. 07/févr./2008 21:48
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 ?

Publié : jeu. 07/févr./2008 22:03
par Le Soldat Inconnu
Je pige pas tout la

Pourquoi tu ne fais pas des Procedure ?

Publié : jeu. 07/févr./2008 22:11
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.

Publié : ven. 08/févr./2008 11:44
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

Publié : ven. 08/févr./2008 12:04
par Backup
c'est etonnant de pouvoir faire cela :)

mais je reste avec mes Gosub tant qu'a faire :)

Publié : ven. 08/févr./2008 12:48
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 


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

Publié : ven. 08/févr./2008 19:27
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