Un pis aller

Partagez votre expérience de PureBasic avec les autres utilisateurs.
PAPIPP
Messages : 534
Inscription : sam. 23/févr./2008 17:58

Un pis aller

Message par PAPIPP »

Bonjour à tous.

Ceci est un pis-aller.
Je suis toujours à la recherche d’une possibilité de :
1) passer des structures complexes en entrée et en sortie d’une procédure.
2) Permettre d’imbriquer les procédures sous forme de fonction explicite u=f(x,y,z)
Voir à ce sujet http://www.purebasic.fr/french/viewtopi ... 5&p=118993

Il est actuellement impossible de passer des structures par valeur >8 octets avec des $00 .On peut par contre passer des structures par adresse.
Imaginons donc une fonction explicite de type *u=f(*x,*y) avec *.. comme pointeur.
Si l’on ne prend aucune précaution *u à toujours la même adresse.
L’exemple suivant est un cas d’école car on peut réaliser l’addition directement mais pour la simplicité de l’exemple j’ai pris l’addition de deux nombres type .d passés en structure en entrée et en sortie.

Code : Tout sélectionner

Procedure.l add_d(*v1.double,*v2.double)
  Static res0.d,NewMap stoc.double()
  ;   Protected res0.d ;; ATTENTION cette option ne fonctionne pas pour une  sortie procedurereturn car la zone est reinitialisée  à chaque appel .et la valeur contenue à l’adresse est perdue sitôt hors du sous/prg
  res0.d=*v1\d+*v2\d
AD_CLF=@res0
  ProcedureReturn AD_CLF
EndProcedure
Gosub subr1
End

subr1:
Debug "********************************* Commence avec une nouvelle protection des variables internes au sous/prg  *******************"
vA1.d=38.00
  vA2.d=48.00
    Debug "******* les adresses et les valeurs *res *res1 *res2 sont différentes elles ne sont écrasées que par la volonté du programmeur *******"
    Debug "******* pour chacun des 3 appels de add_d() *res *res1 *res2 les adresses et les valeurs *res *res1 *res2 restent identiques *******"
   
    *res.double=add_d(@va1,@va2)
      Debug "Va1="+StrD(va1,2)+" +  Va2="+StrD(va2)+" ="+StrD(*res\d)+" adresse="+Hex(*res)+ " *res "
      vA2+1.00
      *res1.double=add_d(@va1,@va2)
      Debug "Va1="+StrD(va1,2)+" +  Va2="+StrD(va2)+" ="+StrD(*res1\d)+" adresse="+Hex(*res1)+" *res1 "
      Debug "*res\d="+StrD(*res\d)+" adresse="+Hex(*res)+" *res "
       vA1+1.00
      *res2.double=add_d(@va1,@va2)
      Debug "Va1="+StrD(va1,2)+" +  Va2="+StrD(va2)+" ="+StrD(*res2\d)+" adresse="+Hex(*res2)+" *res2 "
      Debug  "*res\d="+StrD(*res\d)+" adresse="+Hex(*res)+" *res "
      Debug  "*res1\d="+StrD(*res1\d)+" adresse="+Hex(*res1)+" *res1 "
      
      Debug "************* essai d'imbrication des procédures pour vérifier le résultat  **********"
      va3.d=200.23
      *res3.double=add_d(@Va1,add_d(@vA2,@va3))
      Debug "Va1="+StrD(va1,2)+" +  Va2="+StrD(va2)+" +  Va3="+StrD(va3)+" ="+StrD(*res3\d)+" adresse="+Hex(*res3)+" *res3 add_d() imbriquée"
      Debug  "*res\d="+StrD(*res\d)+" adresse="+Hex(*res)+" *res "
      Debug  "*res1\d="+StrD(*res1\d)+" adresse="+Hex(*res1)+" *res1 "
      Debug  "*res2\d="+StrD(*res2\d)+" adresse="+Hex(*res2)+" *res2 "
      VA1+1.01
      vA2+1.02
      VA3+1.03
      *res4.double=add_d(@Va1,add_d(@vA2,@va3))
      Debug "Va1="+StrD(va1,2)+" +  Va2="+StrD(va2)+" +  Va3="+StrD(va3)+" ="+StrD(*res4\d)+" adresse="+Hex(*res4)+" *res4  add_d() imbriquée"
      Debug  "*res\d="+StrD(*res\d)+" adresse="+Hex(*res)+" *res "
      Debug  "*res1\d="+StrD(*res1\d)+" adresse="+Hex(*res1)+" *res1 "
      Debug  "*res2\d="+StrD(*res2\d)+" adresse="+Hex(*res2)+" *res2 "
      Debug  "*res3\d="+StrD(*res3\d)+" adresse="+Hex(*res3)+" *res3 "

  Return
Vous pouvez remarquer que les différents pointeurs adressent toujours la même zone.
Pour pallier cet inconvénient j’ai ajouté une routine de stockage en MAP dans le sous/prg.

Code : Tout sélectionner

Procedure.l add_d(*v1.double,*v2.double,flag=1)
  Static res0.d,NewMap stoc.double()
  ;   Protected res0.d
  ;********************************************************** Placer ici la fonction  à réaliser ************************************
  res0.d=*v1\d+*v2\d
  ;*********************************************************** fin de la fonction  à réaliser  *********************************
  ; *******************************  contrôle et zone de stockage dans la map *******************************************************
  If flag
;     clef.s=StrD(*v1\d)+"+"+StrD(*v2\d) ; si la zone est plus complexe on peut convertir en HEXA ou en SHA1 MD5 CRC32 ect..
    ; exemple avec crc32
    clef.s=Str(CRC32Fingerprint(*v1,8))+"+"+Str(CRC32Fingerprint(*v2,8)); le signe "+" pour différencier l'opérateur ici addition
    AD_CLF.l=FindMapElement(stoc(),clef)
     If AD_CLF.l<>0
;         Debug "******** c<>0 ********"
        resutm.d=stoc(clef)\d
        If res0<>resutm
          MessageRequester("Collision ", "Collision avec resultats différents res0="+StrD(res0)+"   resutm="+StrD(resutm))
        EndIf
      Else
;         Debug "********* nouvelle entrée  adresse ********"
        AD_CLF=AddMapElement(stoc(),clef)
        stoc(clef)\d=res0
      EndIf
    Else
      ad_clf=@res0
    EndIf
  ProcedureReturn AD_CLF
EndProcedure
Gosub subr1

Debug "**** le résultat est assez claire avec l'option STATIC associée à l'option MAP  permet de consever l'adresse et la valeur  ******"
Debug "**** on peut aussi imbriquer  les appels de procédure comme les instructions PB  ******"
End
; **** Les options SHARED et GLOBAL doivent avoir les mêmes noms entre le sous/prg et PRG principal donc  manque de souplesse

subr1:
Debug "********************************* Commence avec une nouvelle protection des variables internes au sous/prg  *******************"
vA1.d=38.00
  vA2.d=48.00
    Debug "******* les adresses et les valeurs *res *res1 *res2 sont différentes elles ne sont écrasées que par la volontè du programmeur *******"
    Debug "******* pour chacun des 3 appels de add_d() *res *res1 *res2 les adresses et les valeurs *res *res1 *res2 restent identiques *******"
   
    *res.double=add_d(@va1,@va2)
      Debug "Va1="+StrD(va1,2)+" +  Va2="+StrD(va2)+" ="+StrD(*res\d)+" adresse="+Hex(*res)+ " *res "
      vA2+1.00
      *res1.double=add_d(@va1,@va2)
      Debug "Va1="+StrD(va1,2)+" +  Va2="+StrD(va2)+" ="+StrD(*res1\d)+" adresse="+Hex(*res1)+" *res1 "
      Debug "*res\d="+StrD(*res\d)+" adresse="+Hex(*res)+" *res "
       vA1+1.00
      *res2.double=add_d(@va1,@va2)
      Debug "Va1="+StrD(va1,2)+" +  Va2="+StrD(va2)+" ="+StrD(*res2\d)+" adresse="+Hex(*res2)+" *res2 "
      Debug  "*res\d="+StrD(*res\d)+" adresse="+Hex(*res)+" *res "
      Debug  "*res1\d="+StrD(*res1\d)+" adresse="+Hex(*res1)+" *res1 "
      
      Debug "************* essai d'imbrication des procédures pour vérifier le résultat  **********"
      va3.d=200.23
      *res3.double=add_d(@Va1,add_d(@vA2,@va3))
      Debug "Va1="+StrD(va1,2)+" +  Va2="+StrD(va2)+" +  Va3="+StrD(va3)+" ="+StrD(*res3\d)+" adresse="+Hex(*res3)+" *res3 add_d() imbriquée"
      Debug  "*res\d="+StrD(*res\d)+" adresse="+Hex(*res)+" *res "
      Debug  "*res1\d="+StrD(*res1\d)+" adresse="+Hex(*res1)+" *res1 "
      Debug  "*res2\d="+StrD(*res2\d)+" adresse="+Hex(*res2)+" *res2 "
      VA1+1.01
      vA2+1.02
      VA3+1.03
      *res4.double=add_d(@Va1,add_d(@vA2,@va3))
      Debug "Va1="+StrD(va1,2)+" +  Va2="+StrD(va2)+" +  Va3="+StrD(va3)+" ="+StrD(*res4\d)+" adresse="+Hex(*res4)+" *res4  add_d() imbriquée"
      Debug  "*res\d="+StrD(*res\d)+" adresse="+Hex(*res)+" *res "
      Debug  "*res1\d="+StrD(*res1\d)+" adresse="+Hex(*res1)+" *res1 "
      Debug  "*res2\d="+StrD(*res2\d)+" adresse="+Hex(*res2)+" *res2 "
      Debug  "*res3\d="+StrD(*res3\d)+" adresse="+Hex(*res3)+" *res3 "

  Return
  

On peut maintenant, avec cette possibilité, réaliser des procédures explicites avec des structures complexes en entrée et en sortie. Elles seront de type :*u=f(*x,*y,) avec *.. comme pointeur. Elles conservent les résultats précédents et elles permettent l’imbrication *u=f(*x,f(*y,*z)). avec des structures de formes identiques en entrée et en sortie.

En attendant la possibilité de passer des structures complexes par valeurs qui seront certainement plus rapides et plus fiables que cette méthode.

A+
Il est fort peu probable que les mêmes causes ne produisent pas les mêmes effets.(Einstein)
Et en logique positive cela donne.
Il est très fortement probable que les mêmes causes produisent les mêmes effets.