[Résolu] Interface + Procedure avec paramètre List = Erreur

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Geo Trouvpatou
Messages : 471
Inscription : dim. 23/déc./2007 18:10

[Résolu] Interface + Procedure avec paramètre List = Erreur

Message par Geo Trouvpatou »

Salut.
Pourquoi le code me retourne une erreur.
Les interfaces n'acceptent pas de listes chaînées en paramètre de procédure ?

Code : Tout sélectionner

Interface PersonnageObject
      RecevoirDegats(nbDegats.i)
      Attaquer(*adresseVictime)
      BoirePotionDeVie(quantitePotion.i)
      ChangerArme(nomNouvelleArme$, degatsNouvelleArme.i)
      EstVivant.d()
      GetNiveauVie.i()
      SetNewObjetDansInventaire(newElement$)
      GetNewObjetDansInventaire(List ParametreList$())
EndInterface
Dernière modification par Geo Trouvpatou le dim. 18/sept./2011 14:01, modifié 1 fois.
Avatar de l’utilisateur
Ar-S
Messages : 9540
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Interface + Procedure avec paramètre List = Erreur

Message par Ar-S »

Tu les as mis en global tes listes ?
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Geo Trouvpatou
Messages : 471
Inscription : dim. 23/déc./2007 18:10

Re: Interface + Procedure avec paramètre List = Erreur

Message par Geo Trouvpatou »

Salut.

Le problème ici (que tu peux tester), c'est que le paramètre de type "Liste chaînée" n'a pas l'air d'être accepté, alors que pour les paramètres, String, float, integer, aucun problème.
Avatar de l’utilisateur
Ar-S
Messages : 9540
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Interface + Procedure avec paramètre List = Erreur

Message par Ar-S »

Si tu veux bien m'envoyer un exemple compilable ce serait plus facile.
Sans compter que GetNewObjetDansInventaire() j'connais po :wink:
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Geo Trouvpatou
Messages : 471
Inscription : dim. 23/déc./2007 18:10

Re: Interface + Procedure avec paramètre List = Erreur

Message par Geo Trouvpatou »

Le code à compiler en en "PersoDLL.dll"

Code : Tout sélectionner

; Code à compiler en "PersoDLL.dll"

;********************************* 
;* Title : ClassPersonnage
;* Issue du SDZ : http://www.siteduzero.com/tutoriel-3-11167-les-classes-partie-1-2.html#ss_part_1
;* Author : GeoTrouvpatou
;* Date : 16/09/2011 
;* Compatibility 
;* Windows x86 [?] | Windows x64 [Ok] 
;* Linux x86 [?] | Linux x64 [Ok] 
;* MacOs PPC [?] | MacOs intel [?] 
;* Unicode [?] 
;* Demo version [Ok] 
;********************************* 
EnableExplicit

Interface PersonnageObject
      RecevoirDegats(nbDegats.i)
      Attaquer(*adresseVictime)
      BoirePotionDeVie(quantitePotion.i)
      ChangerArme(nomNouvelleArme$, degatsNouvelleArme.i)
      EstVivant.d()
      GetNiveauVie.i()
      SetNewObjetDansInventaire(newElement$)
      GetObjetDansInventaire()
      ;GetObjetDansInventaire2(List ParametreList.s()) ; <------ ERRRRRRRRRRRRRREUR ICI
EndInterface

Interface ExtendsPersonnageObject Extends PersonnageObject
      QuelCouleur()
EndInterface

;-CLASS TEMPLATE.
Structure _PersonnageClassTemplate
      *vTable
      
      ; Attributs privés.
      m_vie.i
      m_mana.i
      m_nomArme$
      m_degatsArme.i 
      nomPersonnage$
      List InventaireObjet$()
      ; A Tester
      ;Map Tools() 
      ;Array MyArray(5) 
EndStructure


ProcedureDLL AttachProcess(instance)
      MessageRequester("Message", "Dll Chargée")
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////



;-CREATE AN INSTANCE OF A PERSONNAGE CLASS.

;/////////////////////////////////////////////////////////////////////////////////
ProcedureDLL.i NewPersonnageObject(personnage$, vie.i = 100) ; personnage$, 
      Protected *object._PersonnageClassTemplate
      ;Attempt to allocate memory for a new class template.
      *object = AllocateMemory(SizeOf(_PersonnageClassTemplate))
      If *object
            ;Make sure the *vTable field points to our virtual table.
            *object\vTable = ?VTable_PersonnageClass
            ;Initialise the length and width.
            *object\m_vie = vie
            *object\nomPersonnage$ = personnage$
            
            ; On initialise certaines valeurs par défaut.
            ; Sinon on aurait pu ajouter des paramètres au constructeur, ou créer une fonction pour initialiser tout ça.
            *object\m_nomArme$ = "Couteau"
            *object\m_degatsArme = 1
            
            InitializeStructure(*object, _PersonnageClassTemplate)
            ;MessageRequester("Mémoire début", Str(*object))
            ; La liste est prête à être utilisée.
            ; Tous les persos ont un couteau dés le début dans leur inventaire.
            AddElement(*object\InventaireObjet$())
            *object\InventaireObjet$() = "Couteau"
            
      EndIf
      ;;MessageRequester("Acces", "Instance créée.")
      ;Return a pointer to our object.
      ; Permet de vérifier que l'instance a bien été créée.
      ProcedureReturn *object
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////



;CLASS METHODS

;/////////////////////////////////////////////////////////////////////////////////
Procedure PersonnageClass_RecevoirDegats(*this._PersonnageClassTemplate, nbDegats.i)
      *this\m_vie = *this\m_vie - nbDegats; // On enlève le nombre de dégâts reçus à la vie du personnage
      
      If *this\m_vie < 0 ;// Pour éviter d'avoir une vie négative
            *this\m_vie = 0 ; // On met la vie à 0 (ça veut dire mort)
      EndIf
      
EndProcedure


Procedure PersonnageClass_Attaquer(*this._PersonnageClassTemplate, *adresseVictime._PersonnageClassTemplate)
      Protected message$
      
      PersonnageClass_RecevoirDegats(*adresseVictime, *this\m_degatsArme)
      
      message$ = "---------- Au Final on peut dire que :" + #CRLF$
      message$ + "L'attaquant est >> : "+ *this\nomPersonnage$ +" >> que son arme est : "+ *this\m_nomArme$ +" >> que le nb de dégat est : "+ Str(*this\m_degatsArme) + #CRLF$
      message$ + "La victime  est >>  : "+ *adresseVictime\nomPersonnage$ +" >> que son arme est : "+ *adresseVictime\m_nomArme$ +" >> que le nb de dégat est : "+ Str(*adresseVictime\m_degatsArme) + #CRLF$
      MessageRequester("Info.", message$)
      
EndProcedure


Procedure PersonnageClass_BoirePotionDeVie(*this._PersonnageClassTemplate, quantitePotion.i)
      *this\m_vie = *this\m_vie + quantitePotion;
      
      If *this\m_vie > 100 ; // Interdiction de dépasser 100 de vie
            *this\m_vie = 100;
      EndIf
EndProcedure


Procedure PersonnageClass_ChangerArme(*this._PersonnageClassTemplate, nomNouvelleArme$, degatsNouvelleArme.i)
      *this\m_nomArme$ = nomNouvelleArme$;
      *this\m_degatsArme = degatsNouvelleArme;
EndProcedure


Procedure.d PersonnageClass_EstVivant(*this._PersonnageClassTemplate)
      ;       If (m_vie > 0) // Plus de 0 de vie ?
      ;             {
      ;             Return true; // VRAI, il est vivant !
      ;             }
      ;       Else
      ;             {
      ;             Return false; // FAUX, il n'est plus vivant !
      ;             }
      
      Debug "Vie restante : "+ Str(*this\m_vie)
      If *this\m_vie > 0 
            ProcedureReturn #True ;// VRAI, il est vivant !
      Else
            ProcedureReturn #False ;// VRAI, il est vivant !
      EndIf
      
EndProcedure



;/////////////////////////////////////////////////////////////////////////////////
Procedure.i PersonnageClass_GetNiveauVie(*this._PersonnageClassTemplate)
      ProcedureReturn *this\m_vie
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////



Procedure PersonnageClass_SetNewObjetDansInventaire(*this._PersonnageClassTemplate, newElement$)
      AddElement(*this\InventaireObjet$())
      *this\InventaireObjet$() = newElement$
      
      ;   ForEach *this\InventaireObjet$()
      ;     Debug *this\InventaireObjet$()
      ;   Next
      
EndProcedure

Procedure.i PersonnageClass_GetObjetDansInventaire(*this._PersonnageClassTemplate)
      Protected inventaire$
      ;MessageRequester("Mémoire fin", Str(*this))
      
      Debug "===== Inventaire arme ====="
      ForEach *this\InventaireObjet$()
            Debug *this\InventaireObjet$()
            inventaire$ + *this\InventaireObjet$() + #CRLF$
      Next
      Debug "======================="
      
      MessageRequester("Info", inventaire$)
      
      ProcedureReturn *this;\InventaireObjet$()
EndProcedure




Procedure.i PersonnageClass_GetObjetDansInventaire2(*this._PersonnageClassTemplate, List ParametreList.s())
      Protected inventaire$
      
      Debug "===== Inventaire arme ====="
      ForEach *this\InventaireObjet$()
            ;While NextElement(*this\InventaireObjet$())
            Debug *this\InventaireObjet$()
            inventaire$ + *this\InventaireObjet$() + #CRLF$
            ;Wend
            AddElement(ParametreList()) : ParametreList() = *this\InventaireObjet$()
            
      Next
      Debug "======================="
      
      MessageRequester("Info", inventaire$)
      
      ProcedureReturn *this;\InventaireObjet$()
EndProcedure



Procedure PersonnageClass_GetColor(*Self)
      MessageRequester("MyObjectEtendu", "Rouge")
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////



;-VIRTUAL TABLES.

;/////////////////////////////////////////////////////////////////////////////////
DataSection 
      VTable_PersonnageClass:
      Data.i @PersonnageClass_RecevoirDegats()
      Data.i @PersonnageClass_Attaquer()
      Data.i @PersonnageClass_BoirePotionDeVie()
      Data.i @PersonnageClass_ChangerArme()
      Data.i @PersonnageClass_EstVivant()
      Data.i @PersonnageClass_GetNiveauVie()
      Data.i @PersonnageClass_SetNewObjetDansInventaire()
      Data.i @PersonnageClass_GetObjetDansInventaire()
      Data.i @PersonnageClass_GetObjetDansInventaire2()
      
      Data.i @PersonnageClass_GetColor()
      
EndDataSection 
;/////////////////////////////////////////////////////////////////////////////////
Le programme utilisant la Dll

Code : Tout sélectionner

;********************************* 
;* Title : ClassPersonnage
;* Issue du SDZ : http://www.siteduzero.com/tutoriel-3-11167-les-classes-partie-1-2.html#ss_part_1
;* Author : GeoTrouvpatou
;* Date : 16/09/2011 
;* Compatibility 
;* Windows x86 [?] | Windows x64 [Ok] 
;* Linux x86 [?] | Linux x64 [Ok] 
;* MacOs PPC [?] | MacOs intel [?] 
;* Unicode [?] 
;* Demo version [Ok] 
;********************************* 
EnableExplicit

Interface PersonnageObject
      RecevoirDegats(nbDegats.i)
      Attaquer(*adresseVictime)
      BoirePotionDeVie(quantitePotion.i)
      ChangerArme(nomNouvelleArme$, degatsNouvelleArme.i)
      EstVivant.d()
      GetNiveauVie.i()
      SetNewObjetDansInventaire(newElement$)
      GetObjetDansInventaire()
      ;GetObjetDansInventaire2(List ParametreList.s()) ; <------ ERRRRRRRRRRRRRREUR ICI
EndInterface


Prototype.i NewPersonnageObject(personnage$, vie.i = 100)

If OpenLibrary(0, "PersoDLL.dll")
      
      ; On récupère l'adresse de notre fonction d'initialisation.
      Global NewObjet.NewPersonnageObject = GetFunction(0, "NewPersonnageObject") ; Renvoi le pointeur de la DLL.
      
      ; Instanciation des Objets
      Define *seb.PersonnageObject = NewObjet("seb", 98)
      Define *goliath.PersonnageObject = NewObjet("goliath")
      
      Debug "-----Niveau de vie DEPART-----"
      Debug "Seb : "+Str(*seb\GetNiveauVie())
      Debug "Goliath : "+Str(*goliath\GetNiveauVie())
      Debug "-------------------------------"
      
      Debug "-----Récup d'armes sur des cadavres puants-----"
      *seb\SetNewObjetDansInventaire("Batte")
      *seb\SetNewObjetDansInventaire("Flingue")
      
      
      Debug "-----L'enfoiré de Gogo attaque le pôv Seb et lui retire 1 point de vie-----"
      *goliath\Attaquer(*seb)
      
      Debug "-----Niveau de vie de Seb-----"
      Debug "Seb : "+Str(*seb\GetNiveauVie())
      
      Debug "-----Seb BOIT POTION qui lui redonne 2 points de vie-----"
      *seb\BoirePotionDeVie(2)
      
      Debug "-----Niveau de vie de Seb après POTION-----"
      Debug "Seb : "+Str(*seb\GetNiveauVie())
      
      
      ; SALOPERIE d'inventaire que je n'arrive à voir qu'avec un MessageRequester
      ; et que j'aimerais bien récupérer dans mon programme principal.
      *seb\GetObjetDansInventaire()
      
      
      ; Bon les objets ne sont pas libérés. Pas encore de FreeMemory dans la Dll.
      
      CloseLibrary(0)
Else
      MessageRequester("Erreur", "Ne peut pas ouvrir la DLL")
EndIf
Mon but serait de pouvoir récupérer ma List InventaireObjet$() dans mon programme principal.
Il me semblait avoir un début de solution avec GetObjetDansInventaire2(List ParametreList.s()), mais apparemment ça ne fonctionne pas dans une interface :cry:.

Bon j'ai nettoyé rapidement le code alors il y a peut-être un peu de code inutile.

Bye.

[EDIT]La class fonctionne à merveille en include, mais hélas pas transformée en Dll. Monde de crotte :cry:.
Dernière modification par Geo Trouvpatou le mer. 12/oct./2011 14:54, modifié 1 fois.
Geo Trouvpatou
Messages : 471
Inscription : dim. 23/déc./2007 18:10

Re: Interface + Procedure avec paramètre List = Erreur

Message par Geo Trouvpatou »

Bon j'ai trouvé une solution qui me convient.

Je nettoie un peu le code et je mettrai la solution.
Geo Trouvpatou
Messages : 471
Inscription : dim. 23/déc./2007 18:10

Re: Interface + Procedure avec paramètre List = Erreur

Message par Geo Trouvpatou »

[EDIT]Je viens de trouver une meilleure soluce qui permet de mieux conserver le coté objet.
Je nettoie et met cette autre solution dans mon post suivant.
Je laisse ce code-ci qui peut toujours servir, puisque fonctionnel aussi.


Cette solution fonctionne, à défaut de trouver mieux, cela me permet de récupérer la liste chaînée de la Dll pour pouvoir l'exploiter dans mon programme principal.

Le code à compiler en "ClassPersonnage.dll"

Code : Tout sélectionner

; Code à compiler en "ClassPersonnage.dll"

;********************************* 
;* Title : ClassPersonnage.dll
;* Issue du SDZ : http://www.siteduzero.com/tutoriel-3-11167-les-classes-partie-1-2.html#ss_part_1
;* Author : GeoTrouvpatou
;* Date : 18/09/2011 
;* Compatibility 
;* Windows x86 [?] | Windows x64 [Ok] 
;* Linux x86 [?] | Linux x64 [Ok] 
;* MacOs PPC [?] | MacOs intel [?] 
;* Unicode [?] 
;* Demo version [Ok] 
;********************************* 
EnableExplicit

Interface PersonnageObject
      DestroyObject()
      RecevoirDegats(nbDegats.i)
      Attaquer(*adresseVictime)
      BoirePotionDeVie(quantitePotion.i)
      ChangerArme(nomNouvelleArme$, degatsNouvelleArme.i)
      EstVivant.d()
      GetNiveauVie.i()
      SetNewObjectDansInventaire(newElement$)
EndInterface

Interface ExtendsPersonnageObject Extends PersonnageObject
      QuelCouleur()
EndInterface

;-CLASS TEMPLATE.
Structure _PersonnageClassTemplate
      *vTable
      
      ; Attributs privés.
      m_vie.i
      m_mana.i
      m_nomArme$
      m_degatsArme.i 
      nomPersonnage$
      List InventaireObjet$()
EndStructure

Structure sInventaire
      List InventaireObjetCopy$()
EndStructure


;/////////////////////////////////////////////////////////////////////////////////
ProcedureDLL AttachProcess(instance)
      MessageRequester("Message", "Dll Chargée")
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////



;-CREATE AN INSTANCE OF A PERSONNAGE CLASS.

;/////////////////////////////////////////////////////////////////////////////////
ProcedureDLL.i NewPersonnageObject(personnage$, vie.i = 100) ; personnage$, 
      Protected *object._PersonnageClassTemplate
      ;Attempt to allocate memory for a new class template.
      *object = AllocateMemory(SizeOf(_PersonnageClassTemplate))
      If *object
            ;Make sure the *vTable field points to our virtual table.
            *object\vTable = ?VTable_PersonnageClass
            ;Initialise the length and width.
            *object\m_vie = vie
            *object\nomPersonnage$ = personnage$
            
            ; On initialise certaines valeurs par défaut.
            ; Sinon on aurait pu ajouter des paramètres au constructeur, ou créer une fonction pour initialiser tout ça.
            *object\m_nomArme$ = "Couteau"
            *object\m_degatsArme = 1
            
            InitializeStructure(*object, _PersonnageClassTemplate)
            ;MessageRequester("Mémoire début", Str(*object))
            ; La liste est prête à être utilisée.
            ; Tous les persos ont un couteau dés le début dans leur inventaire.
            AddElement(*object\InventaireObjet$())
            *object\InventaireObjet$() = "Couteau"
            
      EndIf
      ;;MessageRequester("Acces", "Instance créée.")
      ;Return a pointer to our object.
      ; Permet de vérifier que l'instance a bien été créée.
      ProcedureReturn *object
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////



;CLASS METHODS

;/////////////////////////////////////////////////////////////////////////////////
Procedure PersonnageClass_DestroyObject(*this._PersonnageClassTemplate)
      ;All we need do here is free the memory previously allocated for this object.
      FreeMemory(*this)
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////


;/////////////////////////////////////////////////////////////////////////////////
Procedure PersonnageClass_RecevoirDegats(*this._PersonnageClassTemplate, nbDegats.i)
      *this\m_vie = *this\m_vie - nbDegats; // On enlève le nombre de dégâts reçus à la vie du personnage
      
      If *this\m_vie < 0 ;// Pour éviter d'avoir une vie négative
            *this\m_vie = 0 ; // On met la vie à 0 (ça veut dire mort)
      EndIf
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////


;/////////////////////////////////////////////////////////////////////////////////
Procedure PersonnageClass_Attaquer(*this._PersonnageClassTemplate, *adresseVictime._PersonnageClassTemplate)
      Protected message$
      
      PersonnageClass_RecevoirDegats(*adresseVictime, *this\m_degatsArme)
      
      message$ = "------- Au Final on peut dire que :" + #CRLF$
      message$ + "L'attaquant est >> : "+ *this\nomPersonnage$ +" >> que son arme est : "+ *this\m_nomArme$ +" >> que le nb de dégat est : "+ Str(*this\m_degatsArme) + #CRLF$
      message$ + "La victime  est >>  : "+ *adresseVictime\nomPersonnage$ +" >> que son arme est : "+ *adresseVictime\m_nomArme$ +" >> que le nb de dégat est : "+ Str(*adresseVictime\m_degatsArme) + #CRLF$
      MessageRequester("Info suite à attaque.", message$)
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////


;/////////////////////////////////////////////////////////////////////////////////
Procedure PersonnageClass_BoirePotionDeVie(*this._PersonnageClassTemplate, quantitePotion.i)
      *this\m_vie = *this\m_vie + quantitePotion;
      
      If *this\m_vie > 100 ; // Interdiction de dépasser 100 de vie
            *this\m_vie = 100;
      EndIf
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////


;/////////////////////////////////////////////////////////////////////////////////
Procedure PersonnageClass_ChangerArme(*this._PersonnageClassTemplate, nomNouvelleArme$, degatsNouvelleArme.i)
      *this\m_nomArme$ = nomNouvelleArme$;
      *this\m_degatsArme = degatsNouvelleArme;
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////


;/////////////////////////////////////////////////////////////////////////////////
Procedure.d PersonnageClass_EstVivant(*this._PersonnageClassTemplate)
      ;       If (m_vie > 0) // Plus de 0 de vie ?
      ;             {
      ;             Return true; // VRAI, il est vivant !
      ;             }
      ;       Else
      ;             {
      ;             Return false; // FAUX, il n'est plus vivant !
      ;             }
      
      Debug "Vie restante : "+ Str(*this\m_vie)
      If *this\m_vie > 0 
            ProcedureReturn #True ;// VRAI, il est vivant !
      Else
            ProcedureReturn #False ;// VRAI, il est vivant !
      EndIf
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////


;/////////////////////////////////////////////////////////////////////////////////
Procedure.i PersonnageClass_GetNiveauVie(*this._PersonnageClassTemplate)
      ProcedureReturn *this\m_vie
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////


;/////////////////////////////////////////////////////////////////////////////////
Procedure PersonnageClass_SetNewObjectDansInventaire(*this._PersonnageClassTemplate, newElement$)
      AddElement(*this\InventaireObjet$())
      *this\InventaireObjet$() = newElement$
      
      ;   ForEach *this\InventaireObjet$()
      ;     Debug *this\InventaireObjet$()
      ;   Next
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////


;/////////////////////////////////////////////////////////////////////////////////
Procedure PersonnageClass_GetColor(*Self)
      MessageRequester("MyObjectEtendu", "Rouge")
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////


;/////////////////////////////////////////////////////////////////////////////////
ProcedureDLL GetInventaire(*maListe.sInventaire, *adressePerso._PersonnageClassTemplate) ; personnage$,
      Protected inventaire$
      InitializeStructure(*maListe, sInventaire)
      
      inventaire$ = ">>> Inventaire de "+ *adressePerso\nomPersonnage$ + #CRLF$
      
      Debug "===== Inventaire arme ====="
      ForEach *adressePerso\InventaireObjet$()
            AddElement(*maListe\InventaireObjetCopy$()) : *maListe\InventaireObjetCopy$() = *adressePerso\InventaireObjet$()
            
            Debug *maListe\InventaireObjetCopy$()
            inventaire$ + *maListe\InventaireObjetCopy$() + #CRLF$
      Next
      Debug "======================="
      
      MessageRequester("Inventaire de "+ *adressePerso\nomPersonnage$, inventaire$)   
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////


;-VIRTUAL TABLES.

;/////////////////////////////////////////////////////////////////////////////////
DataSection 
      VTable_PersonnageClass:
      Data.i @PersonnageClass_DestroyObject()
      Data.i @PersonnageClass_RecevoirDegats()
      Data.i @PersonnageClass_Attaquer()
      Data.i @PersonnageClass_BoirePotionDeVie()
      Data.i @PersonnageClass_ChangerArme()
      Data.i @PersonnageClass_EstVivant()
      Data.i @PersonnageClass_GetNiveauVie()
      Data.i @PersonnageClass_SetNewObjectDansInventaire()
      
      Data.i @PersonnageClass_GetColor()
EndDataSection 
;/////////////////////////////////////////////////////////////////////////////////
Le programme utilisant la Dll

Code : Tout sélectionner

;********************************* 
;* Title : Utilisation de : ClassPersonnage.dll
;* Issue du SDZ : http://www.siteduzero.com/tutoriel-3-11167-les-classes-partie-1-2.html#ss_part_1
;* Author : GeoTrouvpatou
;* Date : 18/09/2011 
;* Compatibility 
;* Windows x86 [?] | Windows x64 [Ok] 
;* Linux x86 [?] | Linux x64 [Ok] 
;* MacOs PPC [?] | MacOs intel [?] 
;* Unicode [?] 
;* Demo version [Ok] 
;********************************* 
EnableExplicit

Interface PersonnageObject
      DestroyObject()
      RecevoirDegats(nbDegats.i)
      Attaquer(*adresseVictime)
      BoirePotionDeVie(quantitePotion.i)
      ChangerArme(nomNouvelleArme$, degatsNouvelleArme.i)
      EstVivant.d()
      GetNiveauVie.i()
      SetNewObjectDansInventaire(newElement$)
EndInterface


Structure _PersonnageClassTemplate
      *vTable
      
      ; Attributs privés.
      m_vie.i
      m_mana.i
      m_nomArme$
      m_degatsArme.i 
      nomPersonnage$
      List InventaireObjet$()
EndStructure

Structure sInventaire
      List InventaireObjetCopy$()
EndStructure


Prototype.i Proto_NewPersonnageObject(personnage$, vie.i = 100)
Prototype Proto_GetInventaire(*thisi.sInventaire, *adressePerso._PersonnageClassTemplate) 


If OpenLibrary(0, "ClassPersonnage.dll")
      
      ; On récupère l'adresse de notre fonction d'initialisation.
      Global NewObject.Proto_NewPersonnageObject = GetFunction(0, "NewPersonnageObject") ; Renvoi le pointeur de la DLL.
      Global GetInventaire.Proto_GetInventaire = GetFunction(0, "GetInventaire") 
      
      ; Instanciation des Objets
      Define *seb.PersonnageObject = NewObject("Seb", 98)
      Define *goliath.PersonnageObject = NewObject("Goliath")
      
      Debug "-----Niveau de vie DEPART-----"
      Debug "Seb : "+Str(*seb\GetNiveauVie())
      Debug "Goliath : "+Str(*goliath\GetNiveauVie())
      Debug "-------------------------------"
      
      Debug "-----Récup d'armes sur des cadavres puants-----"
      *seb\SetNewObjectDansInventaire("Batte")
      *seb\SetNewObjectDansInventaire("Flingue")
      
      
      Debug "-----L'enfoiré de Gogo attaque le pôv Seb et lui retire 1 point de vie-----"
      *goliath\Attaquer(*seb)
      
      Debug "-----Niveau de vie de Seb-----"
      Debug "Seb : "+Str(*seb\GetNiveauVie())
      
      Debug "-----Seb BOIT POTION qui lui redonne 2 points de vie-----"
      *seb\BoirePotionDeVie(2)
      
      Debug "-----Niveau de vie de Seb après POTION-----"
      Debug "Seb : "+Str(*seb\GetNiveauVie())
      
      
      
      ; Récupération de l'inventaire dans une liste.
      Define ListeInventaireSeb.sInventaire
      
      
      Debug "======Liste objet(s) dans l'inventaire==========="
      GetInventaire(@ListeInventaireSeb, *seb)
      Debug ListSize(ListeInventaireSeb\InventaireObjetCopy$()) 
      
      ResetList(ListeInventaireSeb\InventaireObjetCopy$())            
      While NextElement(ListeInventaireSeb\InventaireObjetCopy$())
            Debug ListeInventaireSeb\InventaireObjetCopy$() ;on l'affiche
      Wend
      
      
      ; Seb récupère une super grosse sulfateuse.
      *seb\SetNewObjectDansInventaire("Super grosse sulfateuse ki fè plein de mores")
      MessageRequester("Action", "Liste après avoir récupéré une super grosse sulfateuse.")
      
      
      Debug "======Liste objet(s) dans l'inventaire==========="
      GetInventaire(@ListeInventaireSeb, *seb)
      Debug ListSize(ListeInventaireSeb\InventaireObjetCopy$())
      
      ResetList(ListeInventaireSeb\InventaireObjetCopy$()) 
      While NextElement(ListeInventaireSeb\InventaireObjetCopy$())
            Debug ListeInventaireSeb\InventaireObjetCopy$() ;on l'affiche
      Wend
      
      
      
      Debug "======Goliath change d'arme : Hache avec 30 de dégâts et attaque le pôv Seb==========="
      *goliath\ChangerArme("AstéroHache", 30)
      *goliath\Attaquer(*seb)
      
      Debug "-----Niveau de vie de Seb après attaque fulgurante-----"
      Debug "Seb : "+Str(*seb\GetNiveauVie())
      
      Debug "-----Seb se casse, ça vaut mieux pour lui.-----"
      
      
      ; Bon on détruit les objets avant de se barrer pour de nouvelles aventures.
      *seb\DestroyObject()
      *goliath\DestroyObject()
      
      
      CloseLibrary(0)
Else
      MessageRequester("Erreur", "Ne peut pas ouvrir la DLL")
EndIf
Ce jeu s'appelle "Seb contre Goliath".
Sa durée de jeu est d'environ... ... ... :roll: 7 secondes.
Mais comme dirait Actibidon, le jeu est court, mais c'est pour éviter la répététivitée (répétition aurait été plus jolie).

Bye et bon jeu :mrgreen:.
Dernière modification par Geo Trouvpatou le mer. 12/oct./2011 14:57, modifié 2 fois.
Geo Trouvpatou
Messages : 471
Inscription : dim. 23/déc./2007 18:10

Re: Interface + Procedure avec paramètre List = Erreur

Message par Geo Trouvpatou »

Je suis plus content de cette 2ème solution qui me permet de mieux conserver le côté objet.

Le code à compiler en "ClassPersonnage.dll"

Code : Tout sélectionner

; Code à compiler en "ClassPersonnage.dll"

;********************************* 
;* Title : ClassPersonnage.dll
;* Issue du SDZ : http://www.siteduzero.com/tutoriel-3-11167-les-classes-partie-1-2.html#ss_part_1
;* Author : GeoTrouvpatou
;* Date : 18/09/2011 
;* Compatibility 
;* Windows x86 [?] | Windows x64 [Ok] 
;* Linux x86 [?] | Linux x64 [Ok] 
;* MacOs PPC [?] | MacOs intel [?] 
;* Unicode [?] 
;* Demo version [Ok] 
;********************************* 
EnableExplicit

Interface PersonnageObject
      DestroyObject()
      RecevoirDegats(nbDegats.i)
      Attaquer(*adresseVictime)
      BoirePotionDeVie(quantitePotion.i)
      ChangerArme(nomNouvelleArme$, degatsNouvelleArme.i)
      EstVivant.d()
      GetNiveauVie.i()
      SetNewObjectDansInventaire(newElement$)
      GetObjectsInventaire(*maListe)
EndInterface

Interface ExtendsPersonnageObject Extends PersonnageObject
      QuelCouleur()
EndInterface

;-CLASS TEMPLATE.
Structure _PersonnageClassTemplate
      *vTable
      
      ; Attributs privés.
      m_vie.i
      m_mana.i
      m_nomArme$
      m_degatsArme.i 
      nomPersonnage$
      List InventaireObjet$()
EndStructure

Structure sInventaire
      List InventaireObjetCopy$()
EndStructure


;/////////////////////////////////////////////////////////////////////////////////
ProcedureDLL AttachProcess(instance)
      MessageRequester("Message", "Dll Chargée")
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////



;-CREATE AN INSTANCE OF A PERSONNAGE CLASS.

;/////////////////////////////////////////////////////////////////////////////////
ProcedureDLL.i NewPersonnageObject(personnage$, vie.i = 100) ; personnage$, 
      Protected *object._PersonnageClassTemplate
      ;Attempt to allocate memory for a new class template.
      *object = AllocateMemory(SizeOf(_PersonnageClassTemplate))
      If *object
            ;Make sure the *vTable field points to our virtual table.
            *object\vTable = ?VTable_PersonnageClass
            ;Initialise the length and width.
            *object\m_vie = vie
            *object\nomPersonnage$ = personnage$
            
            ; On initialise certaines valeurs par défaut.
            ; Sinon on aurait pu ajouter des paramètres au constructeur, ou créer une fonction pour initialiser tout ça.
            *object\m_nomArme$ = "Couteau"
            *object\m_degatsArme = 1
            
            InitializeStructure(*object, _PersonnageClassTemplate)
            ;MessageRequester("Mémoire début", Str(*object))
            ; La liste est prête à être utilisée.
            ; Tous les persos ont un couteau dés le début dans leur inventaire.
            AddElement(*object\InventaireObjet$())
            *object\InventaireObjet$() = "Couteau"
            
      EndIf
      ;;MessageRequester("Acces", "Instance créée.")
      ;Return a pointer to our object.
      ; Permet de vérifier que l'instance a bien été créée.
      ProcedureReturn *object
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////



;CLASS METHODS

;/////////////////////////////////////////////////////////////////////////////////
Procedure PersonnageClass_DestroyObject(*this._PersonnageClassTemplate)
      ;All we need do here is free the memory previously allocated for this object.
      FreeMemory(*this)
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////


;/////////////////////////////////////////////////////////////////////////////////
Procedure PersonnageClass_RecevoirDegats(*this._PersonnageClassTemplate, nbDegats.i)
      *this\m_vie = *this\m_vie - nbDegats; // On enlève le nombre de dégâts reçus à la vie du personnage
      
      If *this\m_vie < 0 ;// Pour éviter d'avoir une vie négative
            *this\m_vie = 0 ; // On met la vie à 0 (ça veut dire mort)
      EndIf
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////


;/////////////////////////////////////////////////////////////////////////////////
Procedure PersonnageClass_Attaquer(*this._PersonnageClassTemplate, *adresseVictime._PersonnageClassTemplate)
      Protected message$
      
      PersonnageClass_RecevoirDegats(*adresseVictime, *this\m_degatsArme)
      
      message$ = "------- Au Final on peut dire que :" + #CRLF$
      message$ + "L'attaquant est >> : "+ *this\nomPersonnage$ +" >> que son arme est : "+ *this\m_nomArme$ +" >> que le nb de dégat est : "+ Str(*this\m_degatsArme) + #CRLF$
      message$ + "La victime  est >>  : "+ *adresseVictime\nomPersonnage$ +" >> que son arme est : "+ *adresseVictime\m_nomArme$ +" >> que le nb de dégat est : "+ Str(*adresseVictime\m_degatsArme) + #CRLF$
      MessageRequester("Info suite à attaque.", message$)
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////


;/////////////////////////////////////////////////////////////////////////////////
Procedure PersonnageClass_BoirePotionDeVie(*this._PersonnageClassTemplate, quantitePotion.i)
      *this\m_vie = *this\m_vie + quantitePotion;
      
      If *this\m_vie > 100 ; // Interdiction de dépasser 100 de vie
            *this\m_vie = 100;
      EndIf
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////


;/////////////////////////////////////////////////////////////////////////////////
Procedure PersonnageClass_ChangerArme(*this._PersonnageClassTemplate, nomNouvelleArme$, degatsNouvelleArme.i)
      *this\m_nomArme$ = nomNouvelleArme$;
      *this\m_degatsArme = degatsNouvelleArme;
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////


;/////////////////////////////////////////////////////////////////////////////////
Procedure.d PersonnageClass_EstVivant(*this._PersonnageClassTemplate)
      ;       If (m_vie > 0) // Plus de 0 de vie ?
      ;             {
      ;             Return true; // VRAI, il est vivant !
      ;             }
      ;       Else
      ;             {
      ;             Return false; // FAUX, il n'est plus vivant !
      ;             }
      
      Debug "Vie restante : "+ Str(*this\m_vie)
      If *this\m_vie > 0 
            ProcedureReturn #True ;// VRAI, il est vivant !
      Else
            ProcedureReturn #False ;// VRAI, il est vivant !
      EndIf
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////


;/////////////////////////////////////////////////////////////////////////////////
Procedure.i PersonnageClass_GetNiveauVie(*this._PersonnageClassTemplate)
      ProcedureReturn *this\m_vie
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////


;/////////////////////////////////////////////////////////////////////////////////
Procedure PersonnageClass_SetNewObjectDansInventaire(*this._PersonnageClassTemplate, newElement$)
      AddElement(*this\InventaireObjet$())
      *this\InventaireObjet$() = newElement$
      
      ;   ForEach *this\InventaireObjet$()
      ;     Debug *this\InventaireObjet$()
      ;   Next
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////


;/////////////////////////////////////////////////////////////////////////////////
;Procedure PersonnageClass_GetObjectsInventaire(*this._PersonnageClassTemplate, *maListe.sInventaire, *adressePerso._PersonnageClassTemplate) ; personnage$,
Procedure PersonnageClass_GetObjectsInventaire(*this._PersonnageClassTemplate, *maListe.sInventaire) ; personnage$,
      Protected inventaire$
      InitializeStructure(*maListe, sInventaire)
      
      inventaire$ = ">>> Inventaire de "+ *this\nomPersonnage$ + #CRLF$
      
      Debug "===== Inventaire arme ====="
      ForEach *this\InventaireObjet$()
            AddElement(*maListe\InventaireObjetCopy$()) : *maListe\InventaireObjetCopy$() = *this\InventaireObjet$()
            
            Debug *maListe\InventaireObjetCopy$()
            inventaire$ + *maListe\InventaireObjetCopy$() + #CRLF$
      Next
      Debug "======================="
      
      MessageRequester("Inventaire de "+ *this\nomPersonnage$, inventaire$)   
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////


;/////////////////////////////////////////////////////////////////////////////////
Procedure PersonnageClass_GetColor(*Self)
      MessageRequester("MyObjectEtendu", "Rouge")
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////

;-VIRTUAL TABLES.

;/////////////////////////////////////////////////////////////////////////////////
DataSection 
      VTable_PersonnageClass:
      Data.i @PersonnageClass_DestroyObject()
      Data.i @PersonnageClass_RecevoirDegats()
      Data.i @PersonnageClass_Attaquer()
      Data.i @PersonnageClass_BoirePotionDeVie()
      Data.i @PersonnageClass_ChangerArme()
      Data.i @PersonnageClass_EstVivant()
      Data.i @PersonnageClass_GetNiveauVie()
      Data.i @PersonnageClass_SetNewObjectDansInventaire()
      Data.i @PersonnageClass_GetObjectsInventaire()
      
      Data.i @PersonnageClass_GetColor()
EndDataSection 
;/////////////////////////////////////////////////////////////////////////////////
Le programme utilisant la Dll

Code : Tout sélectionner

;********************************* 
;* Title : Utilisation de : ClassPersonnage
;* Issue du SDZ : http://www.siteduzero.com/tutoriel-3-11167-les-classes-partie-1-2.html#ss_part_1
;* Author : GeoTrouvpatou
;* Date : 18/09/2011 
;* Compatibility 
;* Windows x86 [?] | Windows x64 [Ok] 
;* Linux x86 [?] | Linux x64 [Ok] 
;* MacOs PPC [?] | MacOs intel [?] 
;* Unicode [?] 
;* Demo version [Ok] 
;********************************* 
EnableExplicit

Interface PersonnageObject
      DestroyObject()
      RecevoirDegats(nbDegats.i)
      Attaquer(*adresseVictime)
      BoirePotionDeVie(quantitePotion.i)
      ChangerArme(nomNouvelleArme$, degatsNouvelleArme.i)
      EstVivant.d()
      GetNiveauVie.i()
      SetNewObjectDansInventaire(newElement$)
      GetObjectsInventaire(*maListe)
EndInterface


Structure _PersonnageClassTemplate
      *vTable
      
      ; Attributs privés.
      m_vie.i
      m_mana.i
      m_nomArme$
      m_degatsArme.i 
      nomPersonnage$
      List InventaireObjet$()
EndStructure

Structure sInventaire
      List InventaireObjetCopy$()
EndStructure


Prototype.i Proto_NewPersonnageObject(personnage$, vie.i = 100)
;Prototype Proto_GetInventaire(*thisi.sInventaire, *adressePerso._PersonnageClassTemplate) 


If OpenLibrary(0, "ClassPersonnage.dll")
      
      ; On récupère l'adresse de notre fonction d'initialisation.
      Global NewObject.Proto_NewPersonnageObject = GetFunction(0, "NewPersonnageObject") ; Renvoi le pointeur de la DLL.
      ;Global GetInventaire.Proto_GetInventaire = GetFunction(0, "GetInventaire") 
      
      ; Instanciation des Objets
      Define *seb.PersonnageObject = NewObject("Seb", 98)
      Define *goliath.PersonnageObject = NewObject("Goliath")
      
      Debug "-----Niveau de vie DEPART-----"
      Debug "Seb : "+Str(*seb\GetNiveauVie())
      Debug "Goliath : "+Str(*goliath\GetNiveauVie())
      Debug "-------------------------------"
      
      Debug "-----Récup d'armes sur des cadavres puants-----"
      *seb\SetNewObjectDansInventaire("Batte")
      *seb\SetNewObjectDansInventaire("Flingue")
      
      
      Debug "-----L'enfoiré de Gogo attaque le pôv Seb et lui retire 1 point de vie-----"
      *goliath\Attaquer(*seb)
      
      Debug "-----Niveau de vie de Seb-----"
      Debug "Seb : "+Str(*seb\GetNiveauVie())
      
      Debug "-----Seb BOIT POTION qui lui redonne 2 points de vie-----"
      *seb\BoirePotionDeVie(2)
      
      Debug "-----Niveau de vie de Seb après POTION-----"
      Debug "Seb : "+Str(*seb\GetNiveauVie())
      
      
      
      ; Récupération de l'inventaire dans une liste.
      ; On définit une liste pour chaque personnages.
      Define ListeInventaireSeb.sInventaire
      Define ListeInventaireGoliath.sInventaire
      
      
      Debug ">>>>>>>>>>Inventaire de Seb>>>>>>>>>>"
      *seb\GetObjectsInventaire(@ListeInventaireSeb)
      
      Debug "Nb d'objets dans l'inventaire : "+ Str(ListSize(ListeInventaireSeb\InventaireObjetCopy$()))
      ResetList(ListeInventaireSeb\InventaireObjetCopy$()) 
      While NextElement(ListeInventaireSeb\InventaireObjetCopy$())
            Debug ListeInventaireSeb\InventaireObjetCopy$() ;on l'affiche
      Wend       
      Debug "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
      
      
      
      Debug ">>>>>>>>>>Inventaire de Goliath>>>>>>>>"
      *goliath\GetObjectsInventaire(@ListeInventaireGoliath)
      
      Debug "Nb d'objets dans l'inventaire : "+ Str(ListSize(ListeInventaireGoliath\InventaireObjetCopy$()))
      ResetList(ListeInventaireGoliath\InventaireObjetCopy$()) 
      While NextElement(ListeInventaireGoliath\InventaireObjetCopy$())
            Debug ListeInventaireGoliath\InventaireObjetCopy$() ;on l'affiche
      Wend       
      Debug "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
      
      
      ; Seb récupère une super grosse sulfateuse.
      *seb\SetNewObjectDansInventaire("Super grosse sulfateuse ki fè plein de mores")
      MessageRequester("Action", "Liste de Seb après avoir récupéré une super grosse sulfateuse.")
      
      
      Debug ">>>>>>>>>>Inventaire de Seb>>>>>>>>>>"
      *seb\GetObjectsInventaire(@ListeInventaireSeb)
      
      Debug "Nb d'objets dans l'inventaire : "+ Str(ListSize(ListeInventaireSeb\InventaireObjetCopy$()))
      ResetList(ListeInventaireSeb\InventaireObjetCopy$()) 
      While NextElement(ListeInventaireSeb\InventaireObjetCopy$())
            Debug ListeInventaireSeb\InventaireObjetCopy$() ;on l'affiche
      Wend       
      Debug "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
      
      
      
      Debug "======Goliath change d'arme : Hache avec 30 de dégâts et attaque le pôv Seb==========="
      *goliath\ChangerArme("AstéroHache", 30)
      *goliath\Attaquer(*seb)
      
      Debug "-----Niveau de vie de Seb après attaque fulgurante-----"
      Debug "Seb : "+Str(*seb\GetNiveauVie())
      
      Debug "-----Seb se casse, ça vaut mieux pour lui.-----"
      
      
      ; Bon on détruit les objets avant de se barrer pour de nouvelles aventures.
      *seb\DestroyObject()
      *goliath\DestroyObject()
      
      
      CloseLibrary(0)
Else
      MessageRequester("Erreur", "Ne peut pas ouvrir la DLL")
EndIf
Désormais je peux utiliser *seb\GetObjectsInventaire(@ListeInventaireSeb) et donc comme je disais de conserver le côté objet.

Merci à moi-même de m'être aidé :lol:.
Dernière modification par Geo Trouvpatou le mer. 12/oct./2011 15:48, modifié 1 fois.
Avatar de l’utilisateur
Ar-S
Messages : 9540
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: [Résolu] Interface + Procedure avec paramètre List = Err

Message par Ar-S »

bien joué :)
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Geo Trouvpatou
Messages : 471
Inscription : dim. 23/déc./2007 18:10

Re: [Résolu] Interface + Procedure avec paramètre List = Err

Message par Geo Trouvpatou »

Pour clore ce post, Flype avait déjà posé cette question en 2006 et voici ce que Trond lui avait répondu
Répondre