Page 1 sur 1

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

Publié : ven. 16/sept./2011 11:35
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

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

Publié : ven. 16/sept./2011 12:38
par Ar-S
Tu les as mis en global tes listes ?

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

Publié : ven. 16/sept./2011 13:02
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.

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

Publié : ven. 16/sept./2011 17:23
par Ar-S
Si tu veux bien m'envoyer un exemple compilable ce serait plus facile.
Sans compter que GetNewObjetDansInventaire() j'connais po :wink:

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

Publié : ven. 16/sept./2011 18:52
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:.

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

Publié : dim. 18/sept./2011 10:11
par Geo Trouvpatou
Bon j'ai trouvé une solution qui me convient.

Je nettoie un peu le code et je mettrai la solution.

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

Publié : dim. 18/sept./2011 11:48
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:.

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

Publié : dim. 18/sept./2011 13:56
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:.

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

Publié : dim. 18/sept./2011 19:26
par Ar-S
bien joué :)

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

Publié : lun. 26/sept./2011 16:34
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