Page 1 sur 4

Retour tableau alpha contenu dans une DLL pour Pure et VB

Publié : mar. 19/juin/2007 14:32
par Kwai chang caine
Bonjour à tous

J'ai trouvé ce code pour passer un tableau entier à une procedure en argument:

Code : Tout sélectionner

Procedure Test(TableauX, TableauY, TableauAdresse.l) 
  Dim Tableau_Temp(TableauX, TableauY) 
  CopyMemory(TableauAdresse, @Tableau_Temp(), 4 * TableauX * TableauY) ; on copie le tableau dans le tableau temporaire 
  
  Tableau_Temp(0, 0) = 124 
  
  CopyMemory(@Tableau_Temp(), TableauAdresse, 4 * TableauX * TableauY) ; on copie le tableau temporaire dans le tableau 
EndProcedure 

Dim Tableau(5,9) 
Test(5, 9, @Tableau()) 

Debug Tableau(0,0) 
Si le tableau est alphanumerique j'ai modifié ce code comme ça, j'ai juste ou tout faux comme dab ?

Code : Tout sélectionner

Procedure Test(TableauX, TableauY, TableauAdresse.l) 
  Dim Tableau_Temp.s(TableauX, TableauY) 
  CopyMemory(TableauAdresse, @Tableau_Temp(), 8 * TableauX * TableauY) ; on copie le tableau dans le tableau temporaire 
  
  Tableau_Temp.s(0, 0) = "124"
  
  CopyMemory(@Tableau_Temp(), TableauAdresse, 8 * TableauX * TableauY) ; on copie le tableau temporaire dans le tableau 
EndProcedure 

Dim Tableau.s(5,9) 
Test(5, 9, @Tableau()) 

Debug Tableau(0,0) 
Si la fonction est dans une DLL, est ce que ça change quelque chose ???

Je vous remercie de votre aide et vous souhaite une bonne journée

Publié : mar. 19/juin/2007 15:59
par Cls
Je pense que tu peux utiliser la même fonction avec des chaînes de caractères. Il me semble que les chaînes sont stockées sous forme de pointeur dans le tableau (Long, 4 octets).

Code : Tout sélectionner

;- On passe un tableau en parametre de cette fonction
Procedure PassageDuTableau(TableauX, TableauY, TableauAdresse.l) 
  ; Tableau dans lequel seront copiées les données du tableau passé en paramètre
  Dim Tableau.s(TableauX, TableauY) 
  
  ; Copie
  CopyMemory(TableauAdresse, @Tableau(), 4 * TableauX * TableauY)
  
  ; Affichage
  Debug Tableau(0, 0) 
  Debug Tableau(0, 1)
EndProcedure 

Dim Tableau.s(5,9) 
Tableau(0, 0) = "Je suis une chaine ..."
Tableau(0, 1) = "... de caractère !"

PassageDuTableau(5, 9, @Tableau())
Cordialement,
Cls

Publié : mar. 19/juin/2007 17:58
par Flype
En principe,

Sauf à avoir des chaines fixes ( les fameux .s{length} voir meme .c[length] ) il n'est pas possible de copier un tableau de chaines de cette maniere.
Car comme le dit 'Cls' le tableau stocke les pointeurs vers les chaines pas les les chaines elles meme.

Donc il faut faire une boucle et recopier ton tableau dans l'autre ligne par ligne.

Publié : mar. 19/juin/2007 20:29
par Kwai chang caine
@Cls
Merci de ta reponse
D'apres flype mon code n'est pas sur :cry:

@FLYPE
Et ce genre de code est ce que c'est mieux :

Code : Tout sélectionner

ProcedureDll RempliTablo(Tablo.s(1))
 For i = 1 To 5
  Debug Tablo(i)
 Next 
EndProcedure

Dim Tablo.s(5)

For i = 1 To 5
 Tablo(i) = "Phrase " + Str(i)
Next

RempliTablo(Tablo())
Deuxieme question

Comment ferais tu l'inverse, c'est a dire pour exporter un tableau qui serait dans la DLL, pour le lire dans le prg.

Exemple qui ne marche (Comme je sais bien faire :lol:)

Code : Tout sélectionner

ProcedureDLL RempliTablo()

 Dim Tablo.s(5)

 For i = 1 To 5
  Tablo(i) = "Phrase " + Str(i)
 Next
 
 ProcedureReturn @Tablo()

EndProcedure

For i = 1 To 5
 Debug PeekS(RempliTablo())
Next 

Publié : mar. 19/juin/2007 20:55
par Backup
c'est pas plus simple , pour le coup, d'utiliser un Global Dim

et ainsi de s'affranchir de complication intellectuel Masturbatoire ?? :lol:

Publié : mar. 19/juin/2007 21:01
par Kwai chang caine
Bonjour mon bon DOBRO

Dans ce cas oui, mais moi, qui suis pas chiant (comme tu le sais), je voudrais mettre la procedure dans une DLL (Comme c'est ecris dans le titre :wink: )

Et ya pas bon global dans les DLL :D

Publié : mar. 19/juin/2007 22:05
par Cls
Le code que tu proposes initialement correspond à un passage des arguments par adresse (et non par valeur comme tu dois le souhaiter). Cela signifie que les données originelles du tableau ne sont pas préservées (elles sont modifiées par la fonction)...

Une petite précision, histoire de !

Publié : mar. 19/juin/2007 23:28
par Backup
Kwai chang caine a écrit :Bonjour mon bon DOBRO

Dans ce cas oui, mais moi, qui suis pas chiant (comme tu le sais), je voudrais mettre la procedure dans une DLL (Comme c'est ecris dans le titre :wink: )

Et ya pas bon global dans les DLL :D
si!!! en principe un tableau global dans une dll est "locale" a la dll !!

il peut etre global , c'est a dire en dehors des procedures de la dll
et accessible par toutes les procedure de la dll

mais il sera local a la dll , car le prg principal ne pourra pas récupérer les valeurs du tableau !!

bref du Global a la localité de la dll :D



exemple
tu compille ceci en tant que "dll_test.dll"

Code : Tout sélectionner

; code de la dll

Global Dim tableau.s(10)
tableau(5)="dobro"

ProcedureDLL MaFonction()
    MessageRequester("Bonjour", tableau(5), 0)
EndProcedure


et voici le programmes qui exploite la dll

Code : Tout sélectionner

; Voici le programme client qui utilise la DLL
  ;
If OpenLibrary(0, "dll_test.dll")
    CallFunction(0, "MaFonction")
    CloseLibrary(0)
EndIf
:D

Publié : mer. 20/juin/2007 4:46
par Kwai chang caine
Ah d'accord !!!!

@Cls
J'avais pas compris la difference entre les deux méthodes.

En fait, si je comprend bien ce que tu dis, ce serait l'équivalent du byval, byref de VB, chose qui est pas facile pour un debutant comme moi et que j'ai encore du mal a savoir lequel utiliser.
Bah disons que le fait de modifier ou non le tableau m'importe peu, l'important pour moi c'est de pouvoir l'avoir des deux cotés pour travailler avec.

@Dobro
Mais je me suis encore mal exprimé.
Ce que je voudrais c'est avoir un tablo qui est contenu dans la DLL et pouvoir le récupérer dans le programme.

Code de la Dll :

Code : Tout sélectionner

ProcedureDLL RempliTablo() 

 Dim Tablo.s(5) 

 For i = 1 To 5 
  Tablo(i) = "Phrase " + Str(i) 
 Next 
  
 ProcedureReturn @Tablo(1) 

EndProcedure 
Code du prg que je voudrais faire et qui ne marche pas:

Code : Tout sélectionner


Dim tablo.s(5)

If OpenLibrary(0, "dll_test.dll") 

    *AdresseTablo = CallFunction(0, "RempliTablo") 
    
    Tablo(1) = PeekS(*AdresseTablo) 

    For i = 1 To 5 
     Debug  Tablo(i)
   Next 

   CloseLibrary(0) 

EndIf 
ça me retourne des hieroglyphes 8O

Publié : mer. 20/juin/2007 7:14
par Backup
Kwai chang caine a écrit : ça me retourne des hieroglyphes 8O

ça c'est le coté "cloisoné" du PureBasic qui me gonfle !! :twisted:

Publié : mer. 20/juin/2007 7:48
par Kwai chang caine
Tu veux dire que c'est normal 8O

Que ça viens pas de mon code ?

Publié : mer. 20/juin/2007 9:02
par Backup
Kwai chang caine a écrit :Tu veux dire que c'est normal 8O

Que ça viens pas de mon code ?
je ne dit pas que c'est normal, personellement , je trouve ton code logic !!
en principe , ça devrai marcher , c'est peut etre un bug !!


pour testé j'ai remplacé ton tableau par une chaine, et ça marche !! !!

donc , dans l'absolu, cela devrai marcher avec un tableau (qui reste une sorte de variable), ta demarche est logic et clair, c'est donc PureBasic qui est mal foutu ou qui bug !

on peut faire :


Code : Tout sélectionner


; code de la dll

ProcedureDLL.s RempliTablo() 
   test$="dobro" 
    ProcedureReturn test$
EndProcedure

Code : Tout sélectionner

; Voici le programme client qui utilise la DLL
  ;
Dim tablo.s(5)

If OpenLibrary(0, "dll_test.dll")
    
    *AdresseTablo = CallFunction(0, "RempliTablo") 
    Debug *AdresseTablo
    Debug   PeekS(*AdresseTablo) 
    
    CloseLibrary(0)
    
EndIf 

on peut meme recuperer le premier element d'un tableau

Code : Tout sélectionner

; code de la dll

ProcedureDLL.s RempliTablo() 
    Dim tableau.s(5)
    For t=0 To 5
        tableau(t)="phrase"+Str(t)
    Next t  
    ProcedureReturn tableau(0)
EndProcedure 

Code : Tout sélectionner

; exploite la dll
Dim tablo.s(5)
If OpenLibrary(0, "dll_test.dll") 
    *AdresseTablo = CallFunction(0, "RempliTablo") 
   Debug  PeekS(*AdresseTablo)  
    CloseLibrary(0) 
EndIf 

alors , je ne comprends pas que l'on ne recupere pas les autre element, c'est ça que j'appelle le cloisonage , des murs invisible qui empeche de tourner en rond !! :?


ce genre de probleme sera résolu lorsqu'on pourra retourner plusieurs
paramètre d'une procédure


pouvoir mettre plusieurs procedure return dans la meme procedure

car dans mon exemple on aurai pu faire
comme en GFA de memoire :

Code : Tout sélectionner

; code de la dll

ProcedureDLL.s RempliTablo() 
    Dim tableau.s(5)
    For t=0 To 5
        tableau(t)="phrase"+Str(t)
      ProcedureReturn tableau(t)
    Next t     
EndProcedure 
qui retourne a chaque appel l'element suivant

ou bien

Code : Tout sélectionner

; code de la dll

ProcedureDLL.s RempliTablo() 
    Dim tableau.s(5)
    For t=0 To 5
        tableau(t)="phrase"+Str(t)     
    Next t     

   if tartampion
      ProcedureReturn tableau(5)

   else if toto
      ProcedureReturn tableau(2)
   endif
EndProcedure 
qui retourne un element en fonction d'une condition !!

pour moi le pure sera puissant seulement lorsqu'il pourra faire ça !!
ainsi que

Code : Tout sélectionner

for a = 1 to 20.5 step 5.5
next a 

ça a l'air idiot, mais c'est indispensable ! :D

Publié : mer. 20/juin/2007 9:16
par Kwai chang caine
En bidouillant je suis arrivé a faire apparaitre la premier ligne du tableau, mais pas les autres :?

Code de la DLL_Test :

Code : Tout sélectionner

ProcedureDLL AttachProcess(instance)
 Global Dim Tablo.s(5) 
EndProcedure

ProcedureDLL RempliTablo() 

 For i = 1 To 5 
  Tablo(i) = "Phrase " + Str(i) 
 Next 
  
 ProcedureReturn @Tablo(1) 

EndProcedure 
Code du prg appelant :

Code : Tout sélectionner

Dim tablo.s(5) 

If OpenLibrary(0, "dll_test.dll") 
  
 AdresseTablo.l = CallFunction(0, "RempliTablo") 
 Tablo(1) = PeekS(AdresseTablo) 

 For i = 1 To 5 
  Debug  Tablo(i) 
 Next 

 CloseLibrary(0) 

EndIf 
Si quelqu'un peux mieux faire (ça va pas etre dur :lol:)
Merci

Publié : mer. 20/juin/2007 9:17
par Backup
c'est ce que je viens de t'ecrire juste avant !! :?

Publié : mer. 20/juin/2007 9:18
par Kwai chang caine
J'ai commencé mon post puis un copain est venu me parler 5 mn et quand j'ai validé on a posté en meme temp :wink: