[Résolu][Dll] String en retour de procédure. Bug ou pas bug.

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][Dll] String en retour de procédure. Bug ou pas bug.

Message par Geo Trouvpatou »

Salut.

J'amerais savoir si dans le code ci-dessous il s'agit d'un bug ou non.

Dans l'exemple [1] il s'agit d'une Procedure sans argument avec ReturnString$ qui n'est pas mit en Global.
Le résultat n'est pas bon.

Dans l'exemple [2] il s'agit d'une Procedure sans argument avec ReturnStringEnGlobale$ mit en Global.
Le résultat est bon.

Dans l'exemple [3] il s'agit d'une Procedure avec 1 argument non utilisé avec ReturnStringNONGlobale$ qui n'est pas mit en Global.
Le résultat est bon.
D’ailleurs "ReturnStringNONGlobale$" peut même être mit en "Protected" le résultat est bon aussi.

Code : Tout sélectionner

; [1] Procedure sans argument avec ReturnString$ qui n'est pas mit en Global.

ProcedureDLL.i MaFonction1()
    ReturnString$ = "Test1"
    
    *ReturnString = @ReturnString$
    
    ProcedureReturn *ReturnString
EndProcedure

Debug PeekS(MaFonction1()) ; Resultat bizarroide



; [2] Procedure sans argument avec ReturnStringEnGlobale$ mit en Global.

Global ReturnStringEnGlobale$
ProcedureDLL.i MaFonction2()
    ReturnStringEnGlobale$ = "Test2"
    
    *ReturnString = @ReturnStringEnGlobale$
    
    ProcedureReturn *ReturnString
EndProcedure

Debug PeekS(MaFonction2()) ;  Resultat CORRECT



; [3] Procedure avec 1 argument non utilisé avec ReturnStringNONGlobale$ qui n'est pas mit en Global.

ProcedureDLL.i MaFonction3(varBidonUtiliseeNullePart$)
    ReturnStringNONGlobale$ = "Test3"
    
    *ReturnString = @ReturnStringNONGlobale$
    
    ProcedureReturn *ReturnString
EndProcedure

Debug PeekS(MaFonction3("Bibidondon")) ;  Resultat CORRECT
Une autre petite question :
Quand dans un code situé dans une Dll on utilise le mot-clé "Debug", cela ne fonctionne plus.
Y a t'il un truc à paramétrer dans l'IDE pour que cela continu de fonctionner.
Parce que je suis obligé d'utiliser Messagerequester et c'est moins pratique.

[Autre bug] Sous Linux on ne peut pas modifier la Police du spinGadget (c'était le cas avec la 4.60b3)
Peut-être que cela a été rectifié.

Bye.
Dernière modification par Geo Trouvpatou le ven. 16/sept./2011 12:02, modifié 2 fois.
PAPIPP
Messages : 534
Inscription : sam. 23/févr./2008 17:58

Re: [Dll]Bug ou pas bug. [Bug spinGadget]

Message par PAPIPP »

Bonjour Geo Trouvpatou
Voici un élément de réponse
Il faut utiliser soit l'option static soir l'option shared

Code : Tout sélectionner

PProcedureDLL.i MaFonction1()
	ReturnString$="Test1"
  
	*ReturnString=@ReturnString$
  Debug "Interne à la procédure="+ returnstring$+" ou avec peeks="+PeekS(*ReturnString)
	ProcedureReturn *ReturnString
EndProcedure

Debug PeekS(MaFonction1()) ; Une fois sortie de la procédure la mémoire peut être récupérée
ProcedureDLL MaFonction2()
	Static ReturnString2$="Test2"
  
	*ReturnString2=@ReturnString2$
  
	ProcedureReturn *ReturnString2
EndProcedure
Debug PeekS(MaFonction2()) ; Resultat bizarroideProcedureDLL.i 
ProcedureDLL.s MaFonction3()
	Shared  ReturnString3$
	 ReturnString3$="Test3"
    
	ProcedureReturn ReturnString3$
EndProcedure
Debug MaFonction3()+" shared =" +returnString3$
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.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: [Dll]Bug ou pas bug. [Bug spinGadget]

Message par Backup »

et meme que voici l'explication de ton probleme :)
...........
Dernière modification par Backup le sam. 01/oct./2011 9:14, modifié 1 fois.
Geo Trouvpatou
Messages : 471
Inscription : dim. 23/déc./2007 18:10

Re: [Dll]Bug ou pas bug. [Bug spinGadget]

Message par Geo Trouvpatou »

Salut.

Bon j'ai sorti la grosse artillerie.
Pour la 1ère fois j'ai utilisé concrètement l'outil "Visualisateur de mémoire" (Le "Visualisateur de variables", je connaissais et il m'a bien aidé à de maintes reprises).
Ce qui m'a permis dans ton code Dobro de pister "Test1" en mémoire.

Donc si j'ai bien compris, mettre en Global, Shared ou Static, permet de conserver "Test1" à l'adresse mémoire spécifié même à la fin de la Procedure.

Mais par contre à la place de "Bug", j'aurais dû dire "Fonctionnement différent", parce que comme je le disais dans mon 1er post, le simple fait de mettre un argument de type String, le retour se fait sans Global, Shared ou Static.
On peut même aller jusqu'à mettre la variable en Protected.
Par contre j'ai essayé de mettre un argument a.i et ça fonctionne pas (Résultat bidon)
Bref à croire qu'en mettant une chaine en argument Fred à automatiquement ouvert le truc vers l'extérieur malgré mon Protected.

Code : Tout sélectionner

ProcedureDLL.i MaFonction1(a$)
      Protected ReturnString$
      
      ReturnString$ = "Test1" 
      Debug @ReturnString$ ; Sert pour le visualiseur de mémoire
      
      ProcedureReturn @ReturnString$
EndProcedure

;CallDebugger
Debug MaFonction1("111") ; renvoie bien l'adresse de la variable... seulement ta procedure c'est terminé

Debug PeekS( MaFonction1("111")) ; Resultat NONONONONON bizarroide   .....  ;)
@PAPIPP
"Debug" ne fonctionne plus lorsque l'on compile la Dll, c'est ça que je voulais dire.
Code de la Dll :

Code : Tout sélectionner

ProcedureDLL.i MaFonctionPAPPIP1()
      ReturnStringPAPPIP$="Test1"
      
      *ReturnString=@ReturnStringPAPPIP$
      
      Debug "Interne à la procédure="+ ReturnStringPAPPIP$+" ou avec peeks="+PeekS(*ReturnString)
      
      ProcedureReturn *ReturnString
EndProcedure


ProcedureDLL.i MaFonctionPAPPIP2()
      Static ReturnString2$="Test2"
      
      *ReturnString2=@ReturnString2$
      
      ProcedureReturn *ReturnString2
EndProcedure


ProcedureDLL.s MaFonctionPAPPIP3()
      Shared  ReturnString3$
      ReturnString3$="Test3"
      
      ProcedureReturn ReturnString3$
EndProcedure
Code pour utiliser la Dll :

Code : Tout sélectionner

Prototype Proto_MaFonctionPAPPIP1()
Prototype Proto_MaFonctionPAPPIP2()
Prototype Proto_MaFonctionPAPPIP3()

If OpenLibrary(0, "Dll_code.dll")
      MaFonctionPAPPIP1.Proto_MaFonctionPAPPIP1 = GetFunction(0, "MaFonctionPAPPIP1") ; Renvoi le pointeur de la DLL.
      
      ; 1er cas
      res$ = PeekS(MaFonctionPAPPIP1())
      Debug res$
      
      
      ; 2ème cas
      MaFonctionPAPPIP2.Proto_MaFonctionPAPPIP2 = GetFunction(0, "MaFonctionPAPPIP2")
      res$ = PeekS(MaFonctionPAPPIP2())
      Debug res$
      
      ; 3 ème cas
      MaFonctionPAPPIP3.Proto_MaFonctionPAPPIP3 = GetFunction(0, "MaFonctionPAPPIP3")
      res$ = PeekS(MaFonctionPAPPIP3())
      Debug res$
      
      CloseLibrary(0)
Else
      MessageRequester("", "Dll non trouvée.")
EndIf
J'avais bien vu dans la Doc un passage où il était question qu'il fallait Globaliser les variables de type String si on créait une Dll, mais j'ai eu beau relire la Doc, impossible de remettre mes z'oeils sur ce passage.

Maintenant j'ai juste à tester si il ne risque pas d'y avoir des interférences entre une variable Globalisée dans une Dll et une variable du même nom dans le programme principal.

Sinon merci à vous 2.

Bye.

[EDIT]Aucun problème de collision avec les variables et heureusement parce que si on distribuait une Dll aux gens et qu'on était obligé de leur dire : "Alors surtout n'utilisez pas tel nom ou tel autre nom pour vos variables", ce serait une vrai prise de tête.
gnozal
Messages : 832
Inscription : mar. 07/déc./2004 17:35
Localisation : France
Contact :

Re: [Dll]Bug ou pas bug. [Bug spinGadget]

Message par gnozal »

Purebasic.chm a écrit :Construire une DLL
...

Pour qu'une fonction puisse renvoyer un string, il doit être déclaré en global.

Exemple:

Global ReturnString$

ProcedureDLL.s MaFonction(var.s)
ReturnString$ = var + " test"
ProcedureReturn ReturnString$
EndProcedure

Si le string n'est pas déclaré en global, il sera local à la procédure, et donc libéré lors de la fin de la procédure. Il ne pourra pas être utilisé par le programme appelant la fonction.
http://purebasic.com/french/documentati ... e/dll.html
Geo Trouvpatou
Messages : 471
Inscription : dim. 23/déc./2007 18:10

Re: [Dll]Bug ou pas bug. [Bug spinGadget]

Message par Geo Trouvpatou »

Salut.
Le pire c'est que c'est la 1ère page que j'ai lu.
Mais celle-ci s'est ouverte de sorte que j'ai cru que l'explication était complète.
J'avais pas vu la scrollbarre à droite.

Merci parce que j'ai galéré pour retrouvé ça.
Ouf! je ne suis pas fou, je ne l'avais pas inventé :mrgreen:.

Mais malgré tout, le problème reste entier, parce qu'en mettant un argument de type string, plus besoin de Globaliser pour avoir un return correct.
Ce qui est d'ailleurs contradictoire avec ce que dit la doc dont tu as donné le lien parce qu'avec ça :

Code : Tout sélectionner

ProcedureDLL.i MaFonction1(a$) 
	Protected ReturnString$ 
	 
	ReturnString$ = "Test1"  
	Debug @ReturnString$ ; Sert pour le visualiseur de mémoire 
	 
	ProcedureReturn @ReturnString$ 
EndProcedure 

Debug PeekS( MaFonction1("111")) ; Resultat NONONONONON bizarroide ..... ;)
Ça fonctionne très bien dans le programme principal.

Mais par sécurité et pour compatibilité avec d'autres langages, je mettrais en global.

Allez, je vais mettre en résolu.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: [Résolu][Dll]Bug ou pas bug.

Message par Backup »

............
Dernière modification par Backup le sam. 01/oct./2011 9:14, modifié 1 fois.
Geo Trouvpatou
Messages : 471
Inscription : dim. 23/déc./2007 18:10

Re: [Résolu][Dll]Bug ou pas bug.

Message par Geo Trouvpatou »

Ok, donc plus besoin de se prendre la tête pour savoir si je mets la var en Global, Shared ou Static.

En tout cas les Dll c'est plutôt chiant à utiliser.
J'arrive a faire des bricoles assez simple.
Au début utiliser la Dll avec les prototypes, j'avais un peu de mal, maintenant c'est devenu une gymnastique.
Mais quand il s'agit de récupérer une liste ou une liste dans une structure ou pire encore une liste dans une structure déclarée dans un pointeur de procédure déclaré dans une interface.

Ça fonctionne à merveille en include, mais extirper ça d'une Dll c'est pas du gâteau :|.

Merci pour ton explication.
Répondre