Procedure avec pointeur vers un string en paramètre

Programmation d'applications complexes
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Procedure avec pointeur vers un string en paramètre

Message par Le Soldat Inconnu »

Salut,

j'ai un soucis de pointeur (la sale bête)

un petit exemple sera plus parlant. Quand je fais comme cela, il n'y a pas de soucis. J'espère au moins que cette méthode est correcte. Dites moi quand même si je suis déjà à coté de la plaque.

Code : Tout sélectionner

Procedure String(*Texte.s)
	Debug *Texte
	*Texte = "Bonjour les petits enfants, je vous aime. Vous voulez des gateaux ?"
	Debug *Texte
EndProcedure

Test.s = "Bof"
String(@Test)
Debug Test
Par contre, le string que je passe en paramètre est le string d'une structure, et alors, ça ne marche pas, mais ça ne plante pas non plus niveau debugger

Code : Tout sélectionner

Procedure String(*Texte.s)
	Debug *Texte
	*Texte = "Bonjour les petits enfants, je vous aime. Vous voulez des gateaux ?"
	Debug *Texte
	Debug ""
EndProcedure

Structure Bidule
	Texte.s
	Valeur1.l
	Valeur2.q
	Valeur3.s
EndStructure

Test.Bidule\Texte = "Bof"
Test\Valeur1 = 10
Test\Valeur2 = 11
Test\Valeur3 = "12"

String(@Test\Texte)

Debug Test\Texte
Debug Test\Valeur1
Debug Test\Valeur2
Debug Test\Valeur3
une idée ? :mrgreen:

Merci
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Procedure avec pointeur vers un string en paramètre

Message par djes »

Regarde là : http://www.xs4all.nl/~bluez/datatalk/pu ... d_pointers, à la section strings in structures.
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Re: Procedure avec pointeur vers un string en paramètre

Message par Le Soldat Inconnu »

j'arrive à rien de mieux :|

Ce que je cherche à faire, c'est modifier un string via un pointeur comme si je le modifie avec le chemin direct

en gros arriver à faire

Texte.s = "Machin"

mais comme cela

*Pointeur.s = @Texte.s
*pointeur = "machin chouette"

mais ça ne fonctionne pas du tout
Et comme cela non plus

*Pointeur.i = @Texte.s
PokeS(*pointeur, "machin chouette")

car la longueur du string n'est pas ajusté, elle reste figé.

Alors je cale :cry:
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Procedure avec pointeur vers un string en paramètre

Message par djes »

C'est KCC qui devrait te répondre là dessus, il a pris la tête à Srod pendant des semaines avec ça ;) (http://www.purebasic.fr/english/viewtop ... 90&start=0)
Sinon, pourquoi tu ne fais pas tout simplement comme ça?

Code : Tout sélectionner

Structure Bidule 
  Texte.s 
  Valeur1.l 
  Valeur2.q 
  Valeur3.s 
EndStructure 

Procedure String(*Texte.Bidule) 
  Debug *Texte\Texte
  *Texte\Texte = "Bonjour les petits enfants, je vous aime. Vous voulez des gateaux ?" 
  Debug *Texte\Texte
EndProcedure 

Test.Bidule\Texte = "Bof" 
Test\Valeur1 = 10 
Test\Valeur2 = 11 
Test\Valeur3 = "12" 
String(@Test)
Debug Test\Texte 
Debug Test\Valeur1 
Debug Test\Valeur2 
Debug Test\Valeur3
Autrement, je pense que le bousin devrait ressembler à quelque chose comme ça :

Code : Tout sélectionner

Structure Bidule 
  Texte.s 
  Valeur1.l 
  Valeur2.q 
  Valeur3.s 
EndStructure 

Procedure String(*struc, Offset)
  *str.STRING = *struc+Offset
  Debug *str\s
  *str\s = "Bonjour les petits enfants, je vous aime. Vous voulez des gateaux ?"
  Debug *str\s

EndProcedure 

Test.Bidule\Texte = "Bof" 
Test\Valeur1 = 10 
Test\Valeur2 = 11 
Test\Valeur3 = "12" 
String(@Test, OffsetOf(Bidule\Texte))
Debug Test\Texte
Debug Test\Valeur1 
Debug Test\Valeur2 
Debug Test\Valeur3
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Re: Procedure avec pointeur vers un string en paramètre

Message par Anonyme2 »

ALors, ça

Code : Tout sélectionner

Test.Bidule\Texte = "Bof"
Test\Valeur1 = 10
Test\Valeur2 = 11
Test\Valeur3 = "12"

String(@Test\Texte)
s'explique comme ceci

Si ta structure commence à l'adresse 100 :
@Test\Texte retourne l'adresse mémoire de l'élément (ici 100) et pas le pointeur sur la mémoire allouée pour stocker la chaine.

Il faut passer par les structures chaine car comme Fred l'a déjà dit, cette écriture n'a pas beaucoup de sens :

Code : Tout sélectionner

*Texte.s
La doc dit ceci
C'est pour cette raison qu'un pointeur est une variable dite de type pointeur car son encombrement en mémoire sera lié à la capacité d'adressage mémoire du processeur.
Il en découle qu'affecter un type à un pointeur (*Pointeur.l, *Pointeur.b…) n'a aucun sens puisque l'encombrement mémoire d'un pointeur est imposé par celui d'une adresse et non par celui d'un type.

Note :
- A chaque fois qu'une adresse mémoire doit être stockée dans une variable, il faudrait le faire par l'intermédiaire d'un pointeur. Ceci garanti que l'adresse sera correctement représentée lors de la compilation du code que ce soit par un processeur 32 bits comme par un processeur 64 bits par exemple.

Pointeurs et structures

Attacher une structure à un pointeur (par exemple *MonPoint.Point) permet d'accéder au contenu mémoire de chaque membre de la structure avec le caractère \ .
C'est pour éviter ces problèmes que les structures chaine, byte, word etc. existent nativement dans PB.
Je serais partisan de ne laisser plus qu'un type de pointeur simple, ne pointant sur rien et d'utiliser des pointeurs sur des structures lorsque c'est nécessaire.

Le fait de passer par un pointeur chaine basée sur la structure string permet de passer le pointeur correctement sur l'élément chaine et PB sait récupérer l'adresse réelle de la chaine avec ce pointeur.


Moi je te propose ça (pour être très rigoureux, il faudrait que l'élément texte de la structure soit basé sur la structure string).

Tu peux faire des essais, les deux écritures String(*pt) et String(@Test) fonctionnent.

Code : Tout sélectionner

Procedure String(*Texte.string)
   Debug *Texte\s
   *Texte\s = "Bonjour les petits enfants, je vous aime. Vous voulez des gateaux ?"
   Debug *Texte\s
   Debug ""
EndProcedure

Structure Bidule
   Texte.s
   Valeur1.l
   Valeur2.q
   Valeur3.s
EndStructure

Test.Bidule\Texte = "Bof"
Test\Valeur1 = 10
Test\Valeur2 = 11
Test\Valeur3 = "12"


;// utilise un pointeur sur la chaine pour retrouver correctement l'adresse
*pt.Bidule = @Test

Debug "*pt\Texte = " + *pt\Texte
Debug "*pt\Valeur1 = " + Str(*pt\Valeur1)
Debug "*pt\Valeur2 = " + Str(*pt\Valeur2)
Debug "*pt\Valeur3 " + *pt\Valeur3
Debug ""

 String(*pt)
; String(@Test)

Debug Test\Texte
Debug Test\Valeur1
Debug Test\Valeur2
Debug Test\Valeur3
Debug ""

chaine.string\s = "LSI, on french forum"
Debug "chaine\s avant modif : " +  chaine\s
Debug ""
 String(@chaine)
Debug "chaine\s après modif : " +  chaine\s
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Re: Procedure avec pointeur vers un string en paramètre

Message par Le Soldat Inconnu »

oula oui, c'est compliqué l'affaire.

Merci de vos éclaircissement :)
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: Procedure avec pointeur vers un string en paramètre

Message par Kwai chang caine »

Mon ami DJES a écrit :C'est KCC qui devrait te répondre là dessus, il a pris la tête à Srod pendant des semaines avec ça
Pas tout à fait...
En fait j'ai vu la question de mon ami soldat....et j'me suis dit : "Je peux encore pas aider" :oops:
Parce que la question elle parle des variables structurées, et je n'ai pas encore bien compris ces variables, alors je les utilisent jamais :oops:
Et KCC y parlait des tableaux...alors j'me suis dit....va pas encore dire des conneries :?

D'ailleurs j'en dit tellement que meme quand je crois avoir la reponse....et ben souvent je dis rien...et apres je lis la reponse d'un autre ...et seulement quelquefois, je te l'accorde...je m'en veux parce que je me dit ....nadine boudin c'etait ce que j'aurais dit.
Je suis un adepte de l'adage :"Il vaut mieux se taire et passer pour un con , que parler et prouver que l'on en ai un"
Mais quand je fais le compte des bonnes et mauvaises.....la proportion des mauvaises me conforte a continuer comme ça encore un peu....disons....2 siecles :roll:
Mais apres ...au bout de 10 generations de KCC.....je serais le SRODCC du forum français :D

Désolé, soldat....les gens y posent pas des questions que KCC y connait les reponses.
D'un autre coté....faudrait trouver un plus mauvais que moi et qu'en plus il pose la bonne question...c'est a dire une que je me souviens :oops:
Ca me fait penser que j'ai pas jouer au loto cette semaine :mrgreen:
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Procedure avec pointeur vers un string en paramètre

Message par djes »

Denis> La ligne

Code : Tout sélectionner

String(*pt) 
fonctionne parce que la chaîne est à la première position de la structure; normalement tu devrais mettre

Code : Tout sélectionner

String(*pt + OffsetOf(Bidule\Texte))
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Re: Procedure avec pointeur vers un string en paramètre

Message par Anonyme2 »

Tu as parfaitement raison djes.

Ca permet de voir si y'en a qui suivent :mrgreen:
PureWater
Messages : 2
Inscription : jeu. 03/déc./2009 0:17

Re: Procedure avec pointeur vers un string en paramètre

Message par PureWater »

Commentaire 1 de 2

Bonjour Soldat Inconnu,
Voici ma proposition de code:
Procedure String(*Texte.s)
Debug *Texte
*Texte = "Bonjour les petits enfants, je vous aime. Vous voulez des gateaux ?"
Debug *Texte
Debug ""
EndProcedure

Structure Bidule
Texte.s
Valeur1.l
Valeur2.q
Valeur3.s
EndStructure

Test.Bidule\Texte = "Bof" ; ne contient que TROIS caractères
; et la procédure String va essayer d'y placer les 67 caractères de "Bonjour ..."
; le programme ne CRASH pas dans la procédure String, coup de chance ?

; PROPOSITION
;la ligne précédente doit devenir
Test.Bidule\Texte = Space(67) ; 67 ou bien #LEN_MAX_AUTORISED = 512
Test.Bidule\Texte = "Bof"

Test\Valeur1 = 10
Test\Valeur2 = 11
Test\Valeur3 = "12"

String(@Test\Texte )

Debug Test\Texte
Debug Test\Valeur1
Debug Test\Valeur2
Debug Test\Valeur3

PureWater
PureWater
Messages : 2
Inscription : jeu. 03/déc./2009 0:17

Re: Procedure avec pointeur vers un string en paramètre

Message par PureWater »

Commentaire 2 de 2

Dans a procedure String *Texte doit pointer sur un espace mémoire suffisament large que pour recevoir une chaîne de caractères longue comme dans l'exemple : "Bonjour ...."

Illustration par le code qui suit:
Procedure String(*Texte.s)
Debug *Texte
*Texte = "Bof"
Debug *Texte
Debug ""
EndProcedure

Structure Bidule
Texte.s
Valeur1.l
Valeur2.q
Valeur3.s
EndStructure


Test.Bidule\Texte = "Bonjour les petits enfants, je vous aime. Vous voulez des gateaux ?"

Test\Valeur1 = 10
Test\Valeur2 = 11
Test\Valeur3 = "12"

String(@Test\Texte)

Debug Test\Texte
Debug Test\Valeur1
Debug Test\Valeur2
Debug Test\Valeur3

PureWater
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Re: Procedure avec pointeur vers un string en paramètre

Message par Le Soldat Inconnu »

Oui, c'est la le hic, je ne connais pas la longueur du texte finale donc ta manipulation n'est pas valable.

Et je ne peux pas non plus modifier la valeur source car elle resté à l'identique car la procedure ne la modifie pas forcément
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Avatar de l’utilisateur
GeBonet
Messages : 453
Inscription : ven. 29/févr./2008 16:17
Localisation : Belgique

Re: Procedure avec pointeur vers un string en paramètre

Message par GeBonet »

Bonjour,
Suis assez en retard par rapport au sujet et d'accord avec Denis + remarque de Djes....
J'ai repris le code de Denis ci-dessous avec des commentaires et debug pour chaque phase des pointeurs...
Cela rend les choses plus explicites !

Code : Tout sélectionner

; ***********************************************************
;                                     POINTEURS : ?????                                    
; *************************************************************
Declare String(*struc, Offset)
; ------------------------------------------------------------
Structure Bidule  
	Texte.s             ; Byte 0+4   pour .s 
	Valeur1.l            ; Byte 4+4   : .l
	Valeur2.q           ; Byte 4+8    : .q          
	Valeur3.s           ; Byte 12+4  : .s                                              
EndStructure                                                     
; ------------------------------------------------------------
    Test.Bidule\Texte = "Bof ceci est un test" ;         
    Test\Valeur1 = 10   ;Test                                      
    Test\Valeur2 = 11                                                 
    Test\Valeur3 = "12"                                              
; ----------------------------------------- ;  Dans le cas d'une structure Test.Bidule\etc... Test=Adresse du Pointeur de la Structure soit ici 
Debug "--------- Avant -----------"   ;  PeekL(Test) donne l'adresse du premier pointeur qui contient le l'adresse du premier élément idem :
;                                                                           ;   
Debug "Avant -"+Str(Test)                                 ;   Ici "Test" c'est l'étiquette de l'adresse qui contient 
                                                                            ;   L'adresse du premier élément de la STRUCTURE... 
                                                                            ;   La preuve c'est que l'adresse trouvée 
Debug "Avant -"+Str(PeekL(Test))                    ;   Là est la même que celle ci-dessous
Debug "           ---------------------------------"        ;    trouvée elle grace à "@Test.Bidule\Texte"
Debug "Avant -"+Str(@Test.Bidule\Texte)        ;   Adresse du premier élément de la structure.... 
;                                                                               Tandis que la chaine commence ou le pointeur "POINTE"...
Debug "Avant -"+PeekS(@Test.Bidule\Texte)  ;   Affichage de la chaine à partir de son adresse... 
Debug Test\Valeur1                                           ;  
Debug Test\Valeur2                                           ;  ON confond souvent l'adresse des pointeurs
Debug Test\Valeur3                                           ;   AVEC l'adresse des données qu'ils pointent.... 
;                                                                         ---------------------------------------------------------------------------------------
Debug "Valeurs passée @Test                      = "+Str(@Test)                                 ; Adresse du début de la Structure
Debug "Valeurs passée OffsetOf(Bidule\Texte)= "+Str(OffsetOf(Bidule\Texte))    ; décallage obtenus avec "OffsetOf(n)" le premier =0
Debug "Valeurs passée OffsetOf(Test\Valeur1)= "+Str(OffsetOf(Bidule\Valeur1)) ; ici ce sera 0 précédent + 4=   4  => premier de Val1
Debug "Valeurs passée OffsetOf(Test\Valeur2)= "+Str(OffsetOf(Bidule\Valeur2)) ;                   4 précédent + 4 =  8  => premier de Val2
Debug "Valeurs passée OffsetOf(Test\Valeur3)= "+Str(OffsetOf(Bidule\Valeur3)) ;                   8 précédent + 8 = 16 => premier de Val3   
;                                                                         ---------------------------------------------------------------------------------------
Debug "avec PeekS : "+PeekS(PeekL(@Test))                                              ;   Affichage de la chaine à partir de son adresse... 
Debug "avec PeekL : "+Str(PeekL(@Test+OffsetOf(Bidule\Valeur1)))          ;   Affichage avec OffsetOf... 4 
Debug "avec PeekQ : "+Str(PeekQ(@Test+OffsetOf(Bidule\Valeur2)))         ;   Affichage  avec OffsetOf... 8  = 4 + 4
Debug "avec PeekS : "+PeekS(PeekL(@Test+OffsetOf(Bidule\Valeur3)))    ;   Affichage  avec OffsetOf... 16 = 8 + 8 de .q)
; ----------------------------------------------------------------------------------------------------------------------------------------
; ATTENTION: OffSetOf(expression) donne la position dans la structure du pointeur de la donnée.
; 
;  Ex: 'ICI "OffsetOf(Test\Valeur2) donne 8...                                                                                                                                                        
;        Ce qui veux dire que le pointeur de Valeur2 se trouve à "PeekL(Test)+8"                                               
;        ou dans ce qui précéde à "@Test+8" ou en faisant PeekQ(@Test+8) doit donner la valeur de variable = 11                        
; ----------------------------------------------------------------------------------------------------------------------------------------
String(@Test, Offset)                                                                                                                
; ----------------------------------------------------------------------------------------------------------------------------------------
;
Debug "--------- Après Procédure -----------"
Debug Test\Texte       
Debug Test\Valeur1    
Debug Test\Valeur2    
Debug Test\Valeur3    
;
; ------------------------------------------------------------
;Procedure String(*struc, Offset)
Procedure String(*struc, Offset)
     Debug "--------- Dans procédure -----------"
     *str.STRING = *struc+Offset
     Debug "Entrèe 1- "+*str\s
     *str\s = "Bonjour les petits enfants, je vous aime. Vous voulez des gateaux ?"
     Debug "Sortie  2- "+*str\s
EndProcedure 
;
Il est vrai que c'est plus simple aussi de passer les STRING dans les derniers point de la structures c'est plus facilement "extensible"... Ou alors simplement utiliser des tableaux comme je l'ai fait avec KCC... Mais qui lui à compliqué un peu plus...
----------------------------------
Pourquoi compliqué ?
Parce qu'il voulait passer un tableau à une DLL...
Puis que celle-ci éventuellement modifie le tableau
Et enfin être récupéré modifié ou non par le module appelant...
Et en plus que cela soit utilisable par VB aussi... ???

Dans ce cas les pointeurs sont utilisé pour passer un "repère mémoire" au lieu des tableaux eux même.
Bref, ça à été fait pour PB... Comme ci-dessous si ça peut vous être utile...

*********************************************************
Premier cas sans Tableau :

Code : Tout sélectionner

; ***************************************************          
;   Exemple de controle de la mémoire par :     (GeBonet)                            
;   Je suis :  "AppelExempleMem01.PB ou Exe"          
;                                                                   PB 4.40 Beta 3           
; -------------------------------------------------------------------; 
; OBJET :  Dans cet exemple les données sont d'abord 
;             écrit dans la mémoire client par le programme client
;
; On passe l'adresse et le nombre à la Dll pour y être traité... 
; et au retour nous avons le résultat qui dans ce cas est 
; une inversion des mots envoyé... 
; *****************************************************          
;   Par facilité les données viennent ici d'un espace DATA
;   mais pourraient venir d'une base de données, d'encodage
;   ou d'un tableau généré... etc. 
;   ---------------------------------------
;   Dans la Dll, il va de soit que les données passé peuvent aussi
;   subir n'importe quel traitement, tri, sauvegarde particulière etc...
;   ---------------------------------------
;   L'objet principal étant de montrer la facilité d'envoyer des données
;   à une Dll et de le récuperer en retour... 
; ****************************************************   
#Bibliotheque=0 : 
OpenLibrary(#Bibliotheque,"ExempleMem01.dll") ; Ouvre la Dll devant lire la mémoire.........  

If OpenConsole()                               ; Ouvre pour afficher    

    Taille=?FinDonne-?DebutDonnee       ;   Calcul de la Taille de la zone des DATA... 
    ;                                                                               ;
    *MemoryID = AllocateMemory(Taille+100)   ; Réservation de la mémoire utile et son Adresse + 100 (réserve)
    *TamponMem=*MemoryID                       ; Garde une copie de l'adresse originale 
    CopyMemory(?DebutDonnee, *MemoryID, Taille) ; Transfert de la zone DATA vers la mémoire réservée
                              ;  On pourrait dans ce cas travailler directement sur la zone DATA...??
    PrintN("=========Debut Client   =========="); 
    ; --------------------------------------------------------------;
    Num=70                          ; 70 = 14 ligne de 5 mots... (Idem Data)
    ;
    ;    Lecture des DATA avec PeekS(...) Avant d'aller dans la DLL....
    For i=1 To Num                                                         
        Mot$=PeekS(*MemoryID+Resultat)       ; Lecture des données à la nouvelle adresse mémoire 
        PrintN(Mot$)                        ; Affiche le mots lu à partir de sa nouvelle place... 
        Resultat + MemoryStringLength(@Mot$)+1 ; Incrémente le pointeur de la longueur du mots lu
        k=k+1:If k=5:PrintN(" "):k=0:EndIf ; Un espace entre chaque groupe de 5 mots lus...   
    Next i                                 ; qui peu symboliser des éléments d'un tableau... 
    ; --------------------------------------------------------------;
    PrintN("=========Fin Client  ============")
    PrintN("")
    PrintN("         Appel de la DLL                              ")
    ; --------------------------------------------------------------;             APPEL DE LA DLL 
    ;
    CallFunction(0,"CreateArray",*TamponMem, Num)  ; Appel Dll qui devrait afficher la même zone mémoire
    ;                                                                                   ; Puis inverser les mots lu et les réécrire à l'envers     
    ; --------------------------------------------------------------;
    PrintN("========= FIN DLL Resultat =====")
    PrintN("  lecture des mots inversé par la Dll...")
    Num=70:*MemoryID=*TamponMem
    Resultat=0:k=0                                                           ; Réinitialisation des pointeurs et compteurs... 
    ;                                                
    ;                                                                      Retour de DLL Et on va relire la mémoire que la DLL à Modifé...  
    ; 
    For i=1 To Num                                                       ;  Et relecture de la mémoire qui cette fois devrait avoir 
        Mot$=PeekS(*MemoryID+Resultat)                    ;  être modifié par la Dll Lecture  à la nouvelle adresse des données
        PrintN(Mot$)                                                         ;   Affiche le mots lu à partir de sa nouvelle place... pour confirmer
        Resultat + MemoryStringLength(@Mot$)+1        ;  Etc... Idem ci dessus
        k=k+1:If k=5:PrintN(" "):k=0:EndIf                       ;            Il va de soit que les "Mot$" peuvent être des élément d'un Tableau...
    Next i                                                                        ;             Ici on évite tout bonnement de passer le tableau... 
    PrintN("========= FIN programme  ======")
    PrintN("Appuyez sur [Entree] pour quitter")
    Input()
    CloseConsole() 
EndIf

End                                                                         
; -------------------------------------------------------------------------------
DataSection
DebutDonnee:
    Data.s "Sujet","Titre","NomFamille","Nom Editeur","AnneeCopyright"
    Data.s "Tourisme","Salvador da Bahia : 100 Colorfotos","Richter","Alpina-Ceu azul de Copacabana","2000"
    Data.s "Histoire","Fisionomía historica de Chile","Eyzaguirre","Editorial universitaria","1999"
    Data.s "Poesie","Oeuvres completes. Tome premier","Boileau","Hachette","1880"
    Data.s "Vie pratique","Manuel scout des arbres","Vieux Castor","Au Lasso (edition Scoutes)","1938"
    Data.s "Album enfant","Nouvelles aventures du petit diable Malice, Les","Scheggia","Chagor","1959"
    Data.s "Enseignement","Allemand sans peine","Cherel","Assimil","1960"
    Data.s "Album enfant","Album des jeunes 1961","Collectif","Selection du Reader's Digest","1960"
    Data.s "Religion","Sainte Bible, La","Collectif","Cerf","1961"
    Data.s "Essai","Presence de Camus","Simon","Renaissance du livre","1961"
    Data.s "Biographie","Napoleon","Bainville","Librairie generale française","1965"
    Data.s "Theatre","Caligula (suivi de) Le malentendu","Camus","Librairie generale française","1966"
    Data.s "Roman policier / espionnage","Toute la verité","West","Librairie generale française","1966"
    Data.s "Theatre","Caligula (suivi de) Le malentendu","Simon","Librairie generale française","1966"
FinDonne:
EndDataSection
; ----------------------------------------------------------------------------------------
Partie de la DLL avec ce premier CAS !

Code : Tout sélectionner

;*************************************************************
;   DLL : à compiler comme "ExempleMem01.Dll"
; ************************************************************
ProcedureDLL AttachProcess2(Instance)
  ;-----------------------------------------------------------------------
  ;						     Initialisation 
  ;				START DLL PROGRAMME 
  ;-----------------------------------------------------------------------
EndProcedure
; ************************************************************
; ************************************************************
;                   Corps de la DLL 
; ************************************************************
ProcedureDLL CreateArray(*Pointeur, Num)

If OpenConsole()            
    PrintN("=======-DEBUT DLL -========")
    PrintN("Pointeur reçus==>"+Str(*Pointeur))
    PrintN("----------------------------------------------")
    For i=1 To Num                                                     ; 70 = 14 ligne de 5 mots... (Idem Data)
        Mot$=PeekS(*Pointeur+Resultat)                     ; Lecture  à la nouvelle adresse des données
        PrintN(Mot$)                                                       ; Affiche le mots lu à partir de la place en mémoire... 
        ;
        Enver$=ReverseString(Mot$)                            ; Inverse le mot ... pour montrer qu'on a fait quelque chose.... 
        PokeS(*Pointeur+Resultat,Enver$)                   ; ***==>>>  Et l'écrit à la même place
        ;
        Resultat + MemoryStringLength(@Mot$)+1      ; Incrémente le pointeur de la longueur du mots lu
        k=k+1:If k=5:PrintN(" "):k=0:EndIf                     ; Un espace entre chaque groupe...   
    Next i                                                                      ;
    PrintN("")
    PrintN("-----             FIN DLL                ------ *" )
EndIf    
    ; -------------------------------------------------------------------  
    ProcedureReturn 
    
EndProcedure  
; ************************************************************
; ************************************************************
;                        Detache la DLL 
; *******************************************************
ProcedureDLL DetachProcess2(Instance)
;                           fin de la DLL
EndProcedure
; *********************************************************
Deuxième cas AVEC TABLEAU
Ici les deux partie sont ensemble pour faciliter le test mais on peut créer la DLL et modifier l'appel pour que cela fonctionne....

Code : Tout sélectionner

; **************************************************************************************
;   Ensemble des deux parties :         ==>  Appel_Dll_Tableau.pb 
;                                                     ET ==>        Dll_AvecTable.pb (Dll)
; **************************************************************************************
;  Programme de Test Sous PB Version 4.31                  :      GeBonet 
;          Appel_Dll_Tableau.pb                                                  22/09/2009
;  -------------------------------------------------------------------------------------------------------
;  Objet :  1- Passage de donnée entre un tableau du programme principal ver DLL 
;               2- Modification dans Dll pour montrer qu'il se passe bien quelque chose
;               3- Retour au programme principal et affiche le Tableau Modifié..... 
; ****************************************************************************************
#Dim1=20
Global Dim ArrayA.s(#Dim1)  ; Ce sera une 4ième forme.
;  -----------------------------------------------                                                     
;       Programme Client de la DLL 
;  -----------------------------------------------
#Bibliotheque=0 
;   OpenLibrary(#Bibliotheque,"Dll_AvecTable.dll")     A LIBERER SI APPEL DLL

Declare CreateArray(*Pointeur,nb)  
; -------------------------------------------------------------------------------------
Restore DebutDonnee
;
If OpenConsole() 
    ; ----------------------------------------------------------------------------------------
    PrintN( "======= AVANT Appel DLL==========")  
    PrintN("")      
    For i=0 To #Dim1-1   
        Read.s ArrayA(i) ;                   adresse         Variable du tableau 
        PrintN("Adresse Initiale : "+Str(@ArrayA(i))+" " +ArrayA(i))             
    Next i  
    PrintN( "=============================")  
    PrintN("Appuyez sur [Entree] pour Appel DLL")  
    Input()    
    ;**************************************************************************
    ;
    ;*adresse=CallFunction(#Bibliotheque,"CreateArray", @ArrayA.s(),#Dim1)  ;  A LIBERER SI APPEL DLL
    *adresse=CreateArray(@ArrayA.s(),#Dim1)  ;
    ;           
    ;**************************************************************************  
    ArrayA.s()=*adresse                              ; Récupère l'adresse du tableau de la DLL 
    PrintN("")       
    PrintN("======= Apres Appel DLL ==========") 
    PrintN("")     
    PrintN("Adresse du tableau de la Dll = "+Str(*adresse))
    For i = 0 To #Dim1-1     ;                          adresse               Variable extrait de l'adresse du tableau initial 
        PrintN("Au retour  ===> " + Str(i)+" Le tableau "+ArrayA(i))
    Next   
    PrintN("")  
    PrintN("========          FIN            =========")  
    PrintN("Appuyez sur [Entree] pour quitter")  
    Input()    
    ; --------------------------------------------------------------------------------------------
EndIf  
CloseLibrary(#Bibliotheque)
CloseConsole()  
End    
;-------------------------------------------------------------------------
DataSection

DebutDonnee:
    Data.s "Sujet","Titre","NomFamille","Nom Editeur","AnneeCopyright"
    Data.s "Tourisme","Salvador da Bahia : 100 Colorfotos","Richter","Alpina-Ceu azul de Copacabana","2000"
    Data.s "Histoire","Fisionomía historica de Chile","Eyzaguirre","Editorial universitaria","1999"
    Data.s "Poesie","Oeuvres completes. Tome premier","Boileau","Hachette","1880"
    Data.s "Vie pratique","Manuel scout des arbres","Vieux Castor","Au Lasso (edition Scoutes)","1938"
    Data.s "Album enfant","Nouvelles aventures du petit diable Malice, Les","Scheggia","Chagor","1959"
    Data.s "Enseignement","Allemand sans peine","Cherel","Assimil","1960"
    Data.s "Album enfant","Album des jeunes 1961","Collectif","Selection du Reader's Digest","1960"
    Data.s "Religion","Sainte Bible, La","Collectif","Cerf","1961"
    Data.s "Essai","Presence de Camus","Simon","Renaissance du livre","1961"
    Data.s "Biographie","Napoleon","Bainville","Librairie generale française","1965"
    Data.s "Theatre","Caligula (suivi de) Le malentendu","Camus","Librairie generale française","1966"
    Data.s "Roman policier / espionnage","Toute la verité","West","Librairie generale française","1966"
    Data.s "Theatre","Caligula (suivi de) Le malentendu","Simon","Librairie generale française","1966"
FinDonne:
    
EndDataSection
; ************************************************************  

;    LA DLL ..............

; ************************************************************  
ProcedureDLL AttachProcess2(Instance)    
; ------------------------------------------------------------------------ 
;						     Initialisation       
;				START DLL PROGRAMME        
;         Dll_AvecTable.pb =>  Dll_AvecTable.Dll
; -----------------------------------------------------------------------  
  Global Taille
  Global Dim ArrayA.s(Taille)  ; Absolument necessaire pour faire exister 
  Global Dim ArrayB.s(Taille) ; le tableau pour la DLL avant même de recevoir quelque chose
    
EndProcedure
; ************************************************************

; ************************************************************
;                   Corps de la DLL 
;
;  Elle lit un tableau ArrayA.s(n) envoyé par l'appelant 
;  qu'elle place dans un tableau à elle qui est ArrayB.s(n)
;  et renvois l'adresse de son tableau  ArrayB.s()
; ************************************************************
ProcedureDLL CreateArray(*Pointeur,nb)  ;
    
    Dim ArrayB(nb)
    ArrayA.s()=*Pointeur
    Taille=ArraySize(ArrayA())
    ; --------------------------------------------------------------------
    ; ATTENTION : Affiché si : OpenConsole()  est utilisé
    ; --------------------------------------------------------------------    
If OpenConsole() 
    PrintN("=======-DEBUT DLL -========")
    PrintN("Adresse dans dll : "+Str(*Pointeur))  ; @ArrayA(0)
    PrintN("----------------------------------------------")
    PrintN(" Taille de ArrayA() dans DLL ="+Str(Taille)) 
    For i=0 To Taille-1                                                     ; ICI IL N'Y A QU'UN PEEK 
         ArrayB(i)=PeekS(@ArrayA(i))                               ; Prise dans la mémoire de ArrayA(i) de la chaine qui s'y trouve...
         PrintN("ArrayB("+Str(i)+") ="+ArrayB(i))               ; Ici il s'agit bien du tableau ArrayB(i) que l'on affiche... 
    Next i
    PrintN("") 
    PrintN("> Inverse les mots dans DLL AVANT renvois... ") 
    Input()
    ; -------------------------------------------------------------------
    ;   C'est ICI que le travaille dans la DLL peux commencer 
    ; -------------------------------------------------------------------   
    For i=0 To Taille-1                               ; Mais le travaille de la DLL Va s'éffectuer 
         For j=Len(ArrayB(i)) To 1 Step-1   ; Boucle d'inversion 
             Mot2$+Mid(ArrayB(i),j,1)              ;    Inversion... 
         Next j                                               ; 
         ArrayB(i)=Str(i)+" - "+ Mot2$           ; On replace la MODIFICATION... qui sera lu dans le corps du programme...
         PrintN(ArrayB(i))                              ; On affiche le contenu du tableau
         Mot2$=""
    Next i
    PrintN("") 
    PrintN("-----             FIN DLL                ------ *") 
    Input()
    ; ----------------------- Fin du travail de la Dll ----------------
    *Adresse=@ArrayB()
    ;CloseConsole()      
EndIf    
   ProcedureReturn *Adresse

EndProcedure  
; ************************************************************

; ************************************************************
;                        Detache la DLL 
; ************************************************************
ProcedureDLL DetachProcess2(Instance)
;                           fin de la DLL
EndProcedure
; ***********************************************************
Voilà, voilà,
C'est peut-être du déjà connus mais pas forcément montré comme ça :wink:
Windows 7 et Windows 8.1 Pb 5.0 jusque 5.24 Lts 64 et 5.3 (64)/b]
“Ceux qui rêvent éveillés ont conscience de mille choses qui échappent à ceux qui ne rêvent qu’endormis.”
-Edgar Allan Poe-
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Re: Procedure avec pointeur vers un string en paramètre

Message par Thyphoon »

Un sujet qui pourrait passer dans les tutos !! :D
Tres intéressant !
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Procedure avec pointeur vers un string en paramètre

Message par Backup »

Thyphoon a écrit :Un sujet qui pourrait passer dans les tutos !! :D

non !

pourquoi ?
parce qu'un tuto se doit de contenir un maximum d'information
pas seulement des commentaires dans le code !

et j'en ai quand meme laissé passé ;)

un tuto devrai etre le recit d'une ou plusieurs personne , amenant
quelqu'un qui ne comprends rien a rien, a comprendre a la fin du tuto

en utilisant des etapes , progressives :)

blabla
code
blabla
code

le tout mis en page
meme si le sujet est tres interressant , il ne contiens pas une seule phrase
interressant un debutant, mais s'adresse a des 'motivés'

bien sur , il peux s'agir d'un tuto pour les pro , mais
je ne trouve pas que ce topic soit un tuto
mais plus une confrontation d'avis differents ...
je ne vois pas de progression dans les propos pour amener a
comprendre
un tuto devrai ressembler a un cours non ?

enfin j'espere que vous comprenez ce que j'entends par Tuto :)
Répondre