Page 3 sur 4

Publié : jeu. 30/juil./2009 16:08
par Kwai chang caine
Papapa pa papaaaaaaa !!!
Plus de DIM 8O
Mais alors, comment elle fait ta femme quand elle a froid aux jambes :lol:

Non sans rire je ne croyais pas ça faisable de remplacer le travail du compilateur 8O
J'suis sincerement épaté 8)

Ouai on se rapproche de la "vraie" programmation......celle dont je reve de savoir faire un jour.
Celle ou on parle a l'oreille des processeurs :roll: hhhuuuummmffff .......

Bon faut que j'me reveille, j'ai du "broad on woodcut" comme il parlerais le processeur :?

Bon j'ai éssayé de faire comme toi et "j'ai pas arrivé" :D
Etonnant non ????? :oops:

Voila, j'ai donc essayé d'adapter ta gestion de la mémoire à ma DLL avec son appel récursif et tout le bastringue......et ben "zob à poil dur" pas moyen :?

Pourtant, j'ai bien fait comme t'as dit, un tableau de string, un autre de pointeur le chr(0) a la fin, et ben je crois que PB il est drolement malin.....y sait que je suis pas doué.... :roll:
C'est pour ça que ça marche pas.....a moi y veux pas me faire plaisir.
Il doit se dire : "Déjà qu'il est pas foutu de me faire un code correct, avec les instructions natives...vl'a que "MOSSIEUR" s'la joue C avec la gestion de la mémoire himself :?

Voila donc ce que je viens de pondre ....
Attention je te conseille de mettre des gants :oops:

Code : Tout sélectionner

ProcedureDLL.l CreateArray() 
   
 Static Passage, xx, *PointerString
 Passage + 1
   
 If Passage = 1
  *PointerString = AllocateMemory(100000 * 4); Tableau de pointeur 
  Lettre.s = "a"
 Else 
  Lettre.s = "b" 
 EndIf
  
 For x = 1 To 5
  xx + 1
  *String = AllocateMemory(Len(RSet("", xx, Lettre)) * 4)
  PokeS(*String, RSet("", xx, Lettre))
  PokeI(*PointerString, *String) 
  *PointerString + (xx * 4)
 Next
 
 If Passage = 1
  CreateArray()
  ;ReAllocateMemory(*StartPointer, (*Pointer - *StartPointer) * 4)
  Passage = 0
  xx = 0
 EndIf
 
 PokeS(*PointerString, Chr(#Null))   
 ProcedureReturn *PointerString
    
EndProcedure

Dim ArrayA.s(0) 
ArrayA() = CreateArray()

For i = 1 To ArraySize(ArrayA())
 Debug "ArrayA = " + ArrayA(i)
Next

Dim ArrayB.s(0)  
ArrayB()=CreateArray()
 
For i=1 To ArraySize(ArrayB()) 
 Debug "ArrayB = " + ArrayB(i)
Next

Publié : jeu. 30/juil./2009 17:18
par Kwai chang caine
Ouyayayaya !!!!

Tu va etre fier de moi CPL, j'ai drolement avancé, ça marche :D
Et en plus j'mle la suis pété ReAllocateMemory....oui "MOSSIEU" :D

Car en fait, l'erreur entre autre etait que je n'arrivais pas a allouer 2 fois 100 000 octets :roll:
Enfin presque.....j'arrive pas a faire detecter les arraysizes :cry:
T'es sur que ça marche les arraysizes ?????? avec les allocatememory.
Si oui, j'dois pas mettre c'qui faut a la fin de mon tableau de pointeur :?

Bon je replonge ...pour chercher

Ssssscccchhhpppllllooouuffff !!!!

Code : Tout sélectionner

ProcedureDLL.l CreateArray() 
   
 Static Passage, xx, *PointerString
 Passage + 1
   
 If Passage = 1
  *PointerString = AllocateMemory(100000 * 4); Tableau de pointeur 
  Lettre.s = "a"
 Else 
  Lettre.s = "b" 
 EndIf
  
 For x = 1 To 5
  xx + 1
  LenString = Len(RSet("", xx, Lettre))
  *String = AllocateMemory(LenString * 4)
  PokeS(*String, RSet("", xx, Lettre))
  PokeI(*PointerString + (xx * 4), *String) 
 Next
 
 If Passage = 1
  CreateArray()
  ReAllocateMemory(*PointerString, (xx * 4) + 4)
  Passage = 0
  xx = 0
 EndIf
 
 PokeI(*PointerString, #Null)
 ProcedureReturn *PointerString
    
EndProcedure

Dim ArrayA.s(0) 
ArrayA() = CreateArray()

Dim ArrayB.s(0)  
ArrayB() = CreateArray()

For i = 1 To 10 ;ArraySize(ArrayA())
 Debug "Premier essai = " + ArrayA(i)
Next
 
For i = 1 To 10 ;ArraySize(ArrayB()) 
 Debug "Second essai = " + ArrayB(i)
Next

Publié : jeu. 30/juil./2009 18:37
par Anonyme
.j'arrive pas a faire detecter les arraysizes
Te casses pas la tête , moi non plus , je ne sais pas comment PB gère ça...
pas de manière optimisé apparemment .
Il doit indexé le tableau et sa taille quelque part en interne ou l'on à pas accès... te prend pas le choux avec sa :D

Publié : ven. 31/juil./2009 6:13
par Kwai chang caine
Ah bon tu me rassure :D
J'ai posé la question a dieu, mais je doute qu'il reponde :cry:

On a d'autre solution dans mon cas de poser un caractere special de fin...ou bien de renvoyer la longueur par quelque moyen que ce soit :roll:

Merci pour toute ton aide 8)

Publié : ven. 31/juil./2009 15:04
par Anonyme
Pour la taille :
MemorySize(*Tab) / 4


@+

Publié : ven. 31/juil./2009 22:00
par Kwai chang caine
Mon Cpl préféré parmis tous les Cpl du monde :D
J'en crois pas mes petits yeux, je crois que ça marche 8O

C'est tellement beau que je n'ose y croire, apres 3 jours de recherche et je ne sais combien d'heure :cry:

Bref ....j'essaierais de mettre en place ta combine dans ma DLL mardi.
J'espere que je vais encore pas trouvé un truc qui coince
KCC y commence a etre mefiant maintenant :roll:

Je te remercie sincerement mille fois de ta precieuse combine et de tout ton soutiens
Apparement c'est exactement ce que je voulais :D

Bon............ XOMBIE, m'a dit que dans ce code je gerais mal la memoire
il m'a corrigé cette gestion, il me reste a adapter son code au tiens et au miens, en fait je met tout dans une bassine et je touille :lol:

Voici sa correction, si ça interesse "quinquin"

Code : Tout sélectionner

Procedure FreePBString(*Address) 
   ; Procedure and method of removing structure strings from memory from freak @ http://www.purebasic.fr/english/viewtopic.php?t=23099&start=0 
   Protected String.String 
   ; 
   PokeL(@String, *Address) 
   ; 
EndProcedure 
ProcedureDLL.l CreateArray(Which.i) 
   ; 
   Define.i xx, *PointerString 
   ; 
   *PointerString = AllocateMemory(100000 << ((SizeOf(Integer) >> 2) + 1)); Tableau de pointeur 
   ; 
   If Which = 1 
      Lettre.s = "a" 
   Else 
      Lettre.s = "b" 
   EndIf 
   ; 
   For x = 1 To 5 
      LenString = Len(RSet("", x, Lettre)) 
      *String = AllocateMemory((LenString << (SizeOf(Character) - 1)) + SizeOf(Character)) 
      PokeS(*String, RSet("", x, Lettre)) 
      PokeI(*PointerString + ((x - 1) << ((SizeOf(Integer) >> 2) + 1)), *String); ((x - 1) << (SizeOf(Integer) >> 2)), *String) 
      xx + 1 
   Next 
   ; 
   *PointerString = ReAllocateMemory(*PointerString, xx << ((SizeOf(Integer) >> 2) + 1)) 
   ; 
   ProcedureReturn *PointerString 
   ; 
EndProcedure 

*MemoryA = CreateArray(1) 

*MemoryB = CreateArray(2) 

SizeA.i = MemorySize(*MemoryA) >> 2 
Debug SizeA 
SizeB.i = MemorySize(*MemoryB) >> 2 
Debug SizeB 

For i = 1 To SizeA 
   Debug "Premier essai = " + PeekS(PeekI(*MemoryA + ((i - 1) << ((SizeOf(Integer) >> 2) + 1)))) 
Next 
  
For i = 1 To SizeB 
   Debug "Premier essai = " + PeekS(PeekI(*MemoryB + ((i - 1) << ((SizeOf(Integer) >> 2) + 1)))) 
Next 

Debug "Free A..." 
For i = 1 To SizeA 
   FreePBString(PeekI(*MemoryA + ((i - 1) << ((SizeOf(Integer) >> 2) + 1)))) 
Next 
  
Debug "Free B..." 
For i = 1 To SizeB 
   FreePBString(PeekI(*MemoryB + ((i - 1) << ((SizeOf(Integer) >> 2) + 1)))) 
Next 
  
FreeMemory(*MemoryA) 

FreeMemory(*MemoryB)
On sent que c'est pas du KCC code...hein !!!! :oops:
Noir de chose que je ne connais pas :roll:

Au passage, comme je demandais une solution pour connaitre l'arraysize d'un tableau, il m'a fait aussi un super code avec le language de mes reves......
Mais la, on en parle meme pas, c'est pas que je comprend pas quelques instructions......c'est que je comprend que deux lignes :oops: :lol:

Mais ça fait rien, c'est tellement beau l'ASM, je suppose qu'il va lire justement ou FRED il ecris la taille de l'array :roll:

Code : Tout sélectionner

! extrn _SYS_ReAllocateArray@8 
ProcedureDLL.l CreateArray(Array a.s(1), Lettre$) 
   ; 
   Define.l xx 
   ; 
   ! PUSH dword [p.a_a] 
   ! MOV Eax, 5 
   ! PUSH Eax 
   ! CALL _SYS_ReAllocateArray@8 
   ; 
   For x = 1 To 5 
      a(x - 1) = RSet("", x, Lettre$) 
   Next 
   ; 
EndProcedure 

Dim ArrayA.s(0) 
CreateArray(ArrayA(), "a") 
Debug ArraySize(ArrayA()) 

Dim ArrayB.s(0)  
CreateArray(ArrayB(), "b") 
Debug ArraySize(ArrayB()) 

For i = 0 To ArraySize(ArrayA()) 
 Debug "Premier essai = " + ArrayA(i) 
Next 
  
For i = 0 To ArraySize(ArrayB()) 
 Debug "Second essai = " + ArrayB(i) 
Next
C'est dingue ce qu'en quelque lignes on peut faire en ASM 8O
Bon si avec vous deux j'arrive pas a faire peter la banque :D

Voila....je crois que je vous ai tout dit
Ah non...voici donc ce que je recherchais ...sans la correction de la gestion de memoire que m'a proposé XOMBIE

Code : Tout sélectionner

ProcedureDLL.l CreateArray(Parametre) 
    
 Static Passage, xx, *PointerString 
 Passage + 1 
    
 If Passage = 1 
  *PointerString = AllocateMemory(100000 * 4); Tableau de pointeur 
  If Parametre = 1
   Lettre.s = "a"
  Else
   Lettre.s = "c"
  EndIf 
 Else 
  If Parametre = 2
   Lettre.s = "b" 
  Else
   Lettre.s = "d"
  EndIf 
 EndIf 
  
 For x = 1 To 4 
  xx + 1 
  LenString = Len(RSet("", xx, Lettre)) 
  *String = AllocateMemory(LenString * 4) 
  PokeS(*String, RSet("", xx, Lettre)) 
  PokeI(*PointerString + (xx * 4), *String) 
 Next 
  
 If Passage = 1 
  CreateArray(Parametre) 
  ReAllocateMemory(*PointerString, (xx * 4) + 4) 
  Passage = 0 
  xx = 0 
 EndIf 
  
 PokeI(*PointerString, #Null) 
 ProcedureReturn *PointerString 
    
EndProcedure 

Dim ArrayA.s(0) 
ArrayA() = CreateArray(1) 
  
Dim ArrayB.s(0)  
ArrayB() = CreateArray(2) 

For i = 1 To (MemorySize(ArrayA()) / 4) - 1 
 Debug "Premier essai = " + ArrayA(i) 
Next 

For i = 1 To (MemorySize(ArrayB()) / 4) - 1  
 Debug "Second essai = " + ArrayB(i) 
Next
Voila......cette fois je crois que j'ai tout dit jusqu'a ma prochaine tuile

Cpl et Xombie je vous aime :D
Je vous souhaite à tous une bonne soirée

Publié : lun. 03/août/2009 16:28
par GeBonet
Bonjour,

Je viens de trouver ce post... Et j'aimerais y apporter une forme de contribution avec le code ci-dessous qui échange des données mais pas
à partir de tableau mais de mémoire réservée. Ce qui pour moi est presque la même chose.
Car c'est assez simple de récupérer dans un tableau ce qui est rangé en mémoire si on sait ou cela se trouve... :?

Et c'est ce que ce morceau de code fait... De plus j'y joins un morceau de la "doc" relatif au tableau qui s'applique dans ce cas !

Code : Tout sélectionner

;  *************************************************************************************************** 
;  Indépendament des tableaux la mémoire octroyé par  :
;  AllocateMemory(nnnn) ou ReAllocateMemory(*MemoireID, mmmm)
;  Reste octroyé jusqu'au moment ou FreeMemory(*MemoireID) est utilisé ou la fin du programme ! 
; 
;  D'ou l'affectation de cette mémoire est gérable à souhait comme ci dessous par exemple avec deux ou "N" passages...  
;  ou si l'on veut créer une "DLL" réservoir de donnée auxquelles on a accès en connaissant leurs adresses... 
;
;  =============================================================================
;
ProcedureDLL.l Crebloc(Parametre) 

    Static *MemoireID                       ; Permet de garder la trace de la première valeur octroyé 

    Select Parametre
         
        Case 1
            *MemoireID = AllocateMemory(1000)
            If *MemoireID
                Debug "Passe 1 => Adresse début octroyé dans la DLL : "+Str(*MemoireID)
                Debug "Adresse de début de la zone mémoire commence à partir de <Adresse> jusqu'au 1000 ième octets :"
                PokeS(*MemoireID, "Première chaine rangée dans cette zone au premier passage")
            Else
                Debug "Impossible d'allouer la mémoire demandée !"
            EndIf 
            *Adresse=*MemoireID
        Case 2
            Debug ">>> Au passage Dans DLL 2 : "+PeekS(*MemoireID)
            Precedente=MemorySize(*MemoireID)     ; Mémorise la fin de la première zone (occupée ou non)
            
            *NewMemoireID=ReAllocateMemory(*MemoireID, 2000) 
            Debug "Passe 2 => Nouvelle Adresse début octroyé dans la DLL : "+Str(*MemoireID)
            Pas=Precedente                                        ; Début du deuxième rangement... 
            Message$="Et au deuxième passage"      ; Message rangé au deuxième passage 
            LongueurMessage=Len(Message$)          ; longueur de ce message
            PokeS(*NewMemoireID+Pas,Message$)  ; On range ce message dans la deuxième zone octroyée... 
            For i=1 To 100                                            ; Autres données sauvée en tenant compte de leurs place... 
                PokeS(*NewMemoireID+Pas+LongueurMessage,Str(i))
                Pas=Pas+Len(Str(i))
            Next i
            *Adresse=*NewMemoireID+Precedente
            
    EndSelect 
    ProcedureReturn *Adresse
    
EndProcedure    

; ===========================  Après 
    *Adresse1=Crebloc(1)                                ; Adresse du premier BLOC
       Chaine$=PeekS(*Adresse1)
        Debug "1="+Chaine$
        Debug "------------------------------------------------------"
    *Adresse2=Crebloc(2)                                ; Adresse du second BLOC
        Chaine$=PeekS(*Adresse2)
        Debug "2="+Chaine$
        
    ; Vérifions si la première est toujours là ??? 
    Debug PeekS(*Adresse1)+" <=== Est toujours là !!! "
    
End
;  ====================================================================================
Bien que pour la majorité c'est de l'archi-connu, pour moi ce n'est pas encore ancré...
Et pour ceux qui serait comme moi !

Rappel : Un tableau.s() peux toujours être transformé en une chaine et inversément grace à FindString() et StringField()
donc la forme ci dessus est parfaitement utilisable...

EXTRAIT DE LA DOC : Les tableaux sont toujours locaux par défaut, donc pour accéder à partir d'une procedure à un tableau
défini dans le code source principal du programme, l'utilisation de Global ou Shared est requise. Il est également possible de passer
un tableau en paramètre d'une procédure à l'aide du mot clef Array. Il sera passé "par référence"


Soit si j'ai bien compris :

Cela signifie que le tableau ne sera pas copié, et les fonctions dans les procédures manipulerons le tableau original là ou il a été crée,
soit a partir des adresses ou "pointeurs"). Autrement dit un peu comme ci dessus qui sont deux bloc !

J'espère ne pas avoir été trop a coté de la plaque... :? :lol:

Publié : mar. 04/août/2009 8:14
par Kwai chang caine
Merci GEBONET de ta participation

Une vraie galere cette histoire de tableau
En fait ils sont gérés de X manieres selon leurs types.

Je crois que cette fois KCC, il a compris

Les données sont à la queue leu leu pour les numeriques, et aussi les alphanumeriques, mais dans ce dernier cas seulement si ils sont formatés.

Autrement, comme on ne connait pas la longueur de chaque enregistrement effectivement, on se promene comme un representant avec l'echantillon et tout le stock y reste au depot.

Et c'est la que c'est le foutoir, ...........car on crois avoir tout dans le coffre de la bagnole, et en fait on a que les "boites" vides.

Pour avoir le tableau complet, il faut le formater ou bien si il n'est pas trop long le concatener avec un separateur.

Maintenant avec toutes ces methodes ....et grace aux amis qui m'ont aidés, je vais pouvoir jongler ...jusqu'a la prochaine tuile que je vais prendre sur la mouille :cry:

Il me reste une question tout de meme ...etonnant non ????? :D
Les "PROS" j'entend par la Mr CROSOFT et consor....quelle methode ils utilisent......
Parce que, je dois quand meme pas etre le seul au monde, à vouloir rappatrier un tableau de strings dynamiques d'une DLL :?

Les blocs memoires
L'ASM
Les callBacks...

Ah oui parceque, j'ai oublié de vous dire....
Mon ami IDLE, y m'a donné rien que pour KCC, une nouvelle methode encore, la callback qui m'a dit 8O

Il est drolement gaté KCC, il est fier d'avoir autant d'amis, qui l'aide a pallier le handicap neuronal qui l'accable 8)

J'avoue que j'ai pas encore eu le temps de regarder, mais ça m'a l'air top aussi :D

Je vous la donne en exclusivité, pour ceux qui ne connaitrais pas :wink:

Code : Tout sélectionner


;this is in your application 
Procedure MyCallBack(ResultString.s) 
  Debug ResultString 
EndProcedure 

;recusive file search in dll 
ProcedureDLL RechercheElement(*fn,StartDirectory.s,pattern.s,Recursive=1) 
  Static strFiles.s 
  Static ct1 
  mDir = ExamineDirectory(#PB_Any, StartDirectory, "*.*")  
  If mDir  
    While NextDirectoryEntry(mDir) 
      If DirectoryEntryType(mDir) = #PB_DirectoryEntry_File 
          Directory$ = StartDirectory 
          FileName.s = DirectoryEntryName(mDir) 
          If FindString(FileName,pattern, 1) 
            FullFileName.s = StartDirectory + "\" + FileName 
            CallFunctionFast(*fn,FullFileName)  
            Ct1 + 1 
          EndIf    
      Else 
         tdir$ = DirectoryEntryName(mDir) 
         If tdir$ <> "." And tdir$ <> ".." 
           If Recursive = 1 
           RechercheElement(*fn,StartDirectory + "\" + tdir$,pattern) 
           EndIf 
         EndIf 
      EndIf 
   Wend 
   FinishDirectory(mDir) 
  EndIf 
  
  ProcedureReturn ct1  

EndProcedure 

Debug RechercheElement(@MyCallBack(),"C:",".pb") 
Voila....alors ........ si quinquin sait dans le public, et seulement si il sait.... :lol: quelle est la methode utilisée professionnelement ????, il prend sa tellecommande et il vote A/B/C ou D.
Ce sera surement pas mon dernier mot....jean pierre :oops:

Publié : mar. 04/août/2009 10:50
par GeBonet
Salut a tous,

Je vas répondre à titre personnel !
Kwai chang caine a écrit : Il me reste une question tout de meme ...etonnant non ????? :D
Les "PROS" j'entend par la Mr CROSOFT et consor....quelle methode ils utilisent......
Parce que, je dois quand même pas être le seul au monde, à vouloir rapatrier un tableau de strings dynamiques d'une DLL :?
Quand je "travaillais", il y a longtemps... Les "strings" et autres tableaux important étaient tous rangés sur disque selon des format définis par leurs type (numérique) et leurs longueurs définies aussi. Il y étaient rangés soit directement par "enregistrement" (ensemble appartenant au même enregistrement (qui pourrait être une Structure ici) ou venant d'un tableau (ligne, colonne) ligne=un enregistrement et les colonnes le "détails".
Du coup pas de problème, on range sur disque de n'importe ou ! et on récupère du disque de n'importe ou ! (Ce que Dobro à suggérer avec raison d'ailleurs...). Pourquoi si c'est un "travaille" se compliquer la vie, et Gnozal à donné le répertoire pour tous si on travaille en réseaux protégé. D'autant d'ailleurs qu'aujourd'hui, la plupart du temps selon la taille que l'on doit transférer les buffers disque sont relativement gros et ne sont pas systématiquement écrit sur disque, ce qui fait que dans le cas de passage vers une Dll il n'y aurait probablement pas de pénalisation de temps de transfert parce qu'il ne passerait pas par le disque.

Maintenant, si l'on veut faire ce que KCC tiens à faire il y a la solution que je propose ci dessus (AllocateMemory() qui agit comme un espèce de "Buffer" perso). La DOC est claire : "il n'y a pas de transfert de tableau, c'est les références qui le sont"... En fait il est inutile de faire "voyager" en mémoire des choses qui y sont déjà... Il suffit de dire ou elle sont ! :?

Maintenant, il est vrai que si c'est écrit dans la DOC, il manque pas mal d'exemples suffisamment concret à ce sujet pour comprendre vraiment le mécanisme utilisé par PB !

Comme par exemple une liste d'adresse crée et placé dans un Tableau type Adresse.s(Ligne,Colonne) qui serait trié dans une "Dll de tri"... :lol:
En principe on crée le tableau.. On envois à la DLL l'ARRAY concerné (adresse)et sur quoi on veux le tri, la DLL connaissant l'adresse et sur quelle colonne, fait le tri... Et répond, Ok, c'est fait. Puis attend l'autre tableau (adresse) qu'on voudra lui faire trier qui ne sera pas forcément le même :lol:

Publié : mar. 04/août/2009 11:45
par Kwai chang caine
Bon bah la tuile elle a pas duré pour me tomber sur le groin :?

J'ai bien l'impression que memorysize ne marche pas non plus, entre une DLL et un EXE :roll:
Surement qu'il fait appel aussi, a la table d'allocation de cette derniere :?

J'ai "DLLisé" le code de CPL et pas moyen non plus de lire la taille memoire alloué avec MemorySize :cry:

J'en ai maaaaaaaaaaaaaaaaaarrrrrreeeee, ouuuuuuiinnnn !!!

Image

Code de l'EXE

Code : Tout sélectionner

Dim ArrayA.s(0) 

If OpenLibrary(0,"c:\dllbator.dll") 

 *PointeurArrayA = CallFunction(0, "CreateArray", "a", 5) 
 ArrayA() = *PointeurArrayA
 
 Dim ArrayB.s(0)  
 *PointeurArrayB = CallFunction(0, "CreateArray", "b", 10) 
 ArrayB() = *PointeurArrayB
 
 Debug *PointeurArrayA
 Debug *PointeurArrayB
 
 For i=1 To (MemorySize(*PointeurArrayA) / 4) - 1 
  Debug "ArrayA = " + ArrayA(i) 
 Next 
 
 For i=1 To (MemorySize(*PointeurArrayB) / 4) - 1 
  Debug "ArrayB = " + ArrayB(i) 
 Next 
 
 CloseLibrary(0)

EndIf
Code de la DLL

Code : Tout sélectionner

ProcedureDLL CreateArray(Char$,NbElement.i) 

; On alloue un tableau de pointeur Dim A.s n'est en fait qu'un tableau de pointeur vers des strings 
; qui se situe ailleurs en mémoire , car on ne peut pas prévoir à l'avance leur longueur vue quelles 
; ne sont pas fixe. 
*Tab = AllocateMemory(NbElement * 4); Tableau de pointeur 


For e = 0 To NbElement-1 
xx+1 
   *String = AllocateMemory(xx+4) 
      For f = 1 To xx 
         PokeS(*String+(f-1),Mid(Char$,1,1)) ; Mid$ au cas ou len(Char$) > 1 
      Next 
         
         ; on construit notre tableau en lui envoyant les pointeurs *String 
         ; les uns derrière les autres. 
         PokeI(*Tab+(e*4),*String) 
Next 

ProcedureReturn *Tab 
EndProcedure 

Publié : mar. 04/août/2009 12:37
par Backup
tu peux toujours continuer la masturbation intellectuel..

le passage par fichier, est on ne peux plus simple , et sur de marcher !! :lol:
surtout pour un malheureux tableaux !

c'est meme la raison d'etre du passage par fichier (transfert lent pour info longues)

car la Ram "devrait" etre reservé aux transfert rapide pour info courtes ; pour le processeur (animations,sprite,graphique temporaire(flipbuffer),calcul..etc ..)


d'ailleurs de memoire il me semble bien que les ordinateurs (je parle d'ordinateur, pas de micro ordinateur) des années 70, écrivaient tout sur bande magnetique ;) parcequ'il geraient des données !!
les langage comme Cobol, Fortran , etaient fait pour gerer les fichiers long !


bon maintenant avec les disques dur, on ne perd pas trop de temps a faire un transfert d'information d'un prg a un autre ..

Microsoft la bien compris puisque tout ses systemes d'exploitations sont accés sur le "Copier-coller" :D
qu'il s'agisse de deplacer un fichier, le copier, ou bien d'une image ou de texte
tout est copier-collé ! , et ça passe par quoi ?
ben par un fichier !! (le press papier)

je pense que ton problème viens simplement du fait que tu ne connaisse pas l'histoire des micro ordinateurs ;)

sinon , tu ne te serai même pas imaginé faire ce transfert de tableau en passant par la ram ...

puisque historiquement la Ram ne sert pas a ça !! :D

mais bon :D

Publié : mar. 04/août/2009 13:08
par Kwai chang caine
tu peux toujours continuer la masturbation intellectuel..
Bah le probleme, c'est quand je suis tout seul dans mon bureau et que j'ai téléchargé un film de clara morgane.
J'ai une main occupé....l'autre sur la souris pour baisser le son.....pour pas que ma femme entende :?

Et j'ai le cerveau qui fait rien et qui est un peu jaloux :twisted:
Parce que les films de clara.... tres souvent "l'intrique"...non c'est un labsus....l'intrigue est tres excitante, mais au niveau des dialogues faut reconnaitre que c'est pas du "audiard" :lol:

Je pense que tu as raison, sur le principe :roll:
Mais tu sais que je ne fais et ne ferais surement jamais de jeux.
Alors c'est aussi ma maniere d'apprendre la programmation bas niveau, et de justement essayer, je dis bien essayer de rattraper le retard de connaissance de l'histoire des ORDINATEURS

En plus j'ai choisi PB, car il savait faire des DLL
Alors c'est pour cette raison que j'aimerais bien comprendre le comportement EXE/DLL avant que je distribue tout ça, et que ça me pete a la gueule :lol:

Publié : mar. 04/août/2009 13:09
par GeBonet
Bon,

Indépendamment de la remarque de Dobro, que je REconfirme comme étant une forme "normale" de passage de donnée...

La forme avec réservation de mémoire que j'avais placée ci-dessus fonctionne...
Et les deux parties suivantes fonctionnent et je les aient compilé et testée...
Donc on peux y mettre ce que l'on veux dans cette mémoire !!!

Code : Tout sélectionner

; ---------------------------------------------------------------------------------
;  PARTIE : a compiler comme DLL, 
; **********************************************************************************************************
ProcedureDLL AttachProcess2(Instance)
  ;------------------------------------------------------------------------------------------------------
  ;						                         Initialisation 
  ;										START DLL PROGRAMME 
  ;------------------------------------------------------------------------------------------------------
EndProcedure
; **********************************************************************************************************
ProcedureDLL.l Crebloc(Parametre) 

    Static *MemoireID                       ; Permet de garder la trace de la première valeur octroyé 

    Select Parametre
         
        Case 1
            *MemoireID = AllocateMemory(1000)
            If *MemoireID
                PokeS(*MemoireID, "Première chaine rangée dans cette zone au premier passage")
            Else
                Debug "Impossible d'allouer la mémoire demandée !"
            EndIf 
            *Adresse=*MemoireID
        Case 2
            Precedente=MemorySize(*MemoireID)     ; Mémorise la fin de la première zone (occupée ou non)
            
            *NewMemoireID=ReAllocateMemory(*MemoireID, 2000) 
            
            Pas=Precedente                                        ; Début du deuxième rangement... 
            Message$="Et au deuxième passage"      ; Message rangé au deuxième passage 
            LongueurMessage=Len(Message$)          ; longueur de ce message
            PokeS(*NewMemoireID+Pas,Message$)  ; On range ce message dans la deuxième zone octroyée... 
            For i=1 To 100                                            ; Autres données sauvée en tenant compte de leurs place... 
                PokeS(*NewMemoireID+Pas+LongueurMessage,Str(i))
                Pas=Pas+Len(Str(i))
            Next i
            *Adresse=*NewMemoireID+Precedente
            
    EndSelect 
    ProcedureReturn *Adresse
    
EndProcedure    
; *********************************************************
ProcedureDLL DetachProcess2(Instance)
;                           fin de la DLL
EndProcedure
Puis ici pour l'exe de cet exemple...

Code : Tout sélectionner

;============================================================
;  Partie à compiler comme EXE ou executer dans l'IDE avec la DLL dessous
;============================================================
;
#Bibliotheque=0
OpenLibrary(#Bibliotheque,"Ma_Dll.dll")
;
    *Adresse1=CallFunction(#Bibliotheque,"Crebloc",1)   ; Adresse du premier BLOC
       Chaine$=PeekS(*Adresse1)
        Debug "1="+Chaine$
        Debug "------------------------------------------------------"
    ; ------------------------------------------------------------------------------------------------------------
    *Adresse2=CallFunction(#Bibliotheque,"Crebloc",2)   ; Adresse du second BLOC
        Chaine$=PeekS(*Adresse2)
        Debug "2="+Chaine$
        
    ; Vérifions si la première est toujours là ??? 
    Debug "Puis ! "
    Debug PeekS(*Adresse1)+" <=== Est toujours là !!! "
   
End
J'espère que cela t'aidera... et que cela rapatrie bien des données crées dans la DLL !!! :?

Publié : mar. 04/août/2009 13:27
par Kwai chang caine
Oui oui GEBO ça marche car en fait tu fait passer une phrase concaténée.
Et donc une seule adresse avec un caractere de fin qui doit etre le chr(0)

Donc dans l'exe, pas de probleme de arraysize ou bien memorysize.
C'est dans les premieres methodes que j'avais exploré, avant de me lancer sur ces ¤ù$¤^¨$ù^# de tableaux :?

Tu utilise contrairement a moi, le allocatememory, moi je laissais faire PB avec les variables string.
Et tu utilise 2 zones memoires, donc la premiere n'est pas touchée :D

Mais imagine que j'appelle cette procedure 30 fois......je ne peux pas faire de case d'un nombre d'appel que je ne connais pas :roll:

Bon apparement, c'est bien ça, PB ne lis pas la place memoire utilisé quand on fait memorysize, il lit un nombre qui a été ecris quelque part comme pour la taille du tableau.
Donc retour au point de depart, sans gagner 10 000 Francs :?

C'est pas grave, je vais chercher une solution avec tous les aides que j'ai eu.
Comme le dit SROD, je pense que je fais comme dab les choses à l'envers.
Car en fait le allocatememory devrait etre fait dans l'exe et transmettre l'ID de l'allocation pour que la DLL la remplisse.
Ou bien....envoyer le tableau pour que la DLL le remplisse des pointeurs de string......

Je trouvais ça tellement simple au debut de pouvoir ecrire juste

Code : Tout sélectionner

Dim Kcc.s(0)
Kcc() = CallFunction(0, "Fonction")
Quand ça parait simple...faut se mefier...la difficulté est souvent un peu plus loin tapie derriere un buisson :?

Quoi qu'il en soit merci encore a tous 8)

Publié : mar. 04/août/2009 14:10
par GeBonet
Ouais...
Le Case ou autre forme ne sont là que pour éclaircir le code... Et montrer l'écriture dans des zones différentes...
Kwai chang caine a écrit : Comme le dit SROD, je pense que je fais comme dab les choses à l'envers.
Car en fait le allocatememory devrait etre fait dans l'exe et transmettre l'ID de l'allocation pour que la DLL la remplisse.
Ou bien....envoyer le tableau pour que la DLL le remplisse des pointeurs de string......
Je trouvais ça tellement simple au debut de pouvoir ecrire juste
Quand au fait d'être à l'envers c'est sur car je t'ai passé un extrait de la DOC qui explique bien que le Tableau existe là ou il est créer ! Tout comme l'AllocateMemory.
Et certainement dans la partie la plus stable... Le corps du programme ! Et non l'inverse.
Aujourd'hui je ne sais pas comment réagissent les dll, mais il y a longtemps elles étaient chargés ou déchargés selon l'utilité et donc devaient être considérées présentent que au moment de l'utilisation !
D'ou le passage par le disque, ou par une réservation mémoire à partir du programme principal.
Donc la dll devrait utiliser les adresses transmises du programme principal pour avoir accès aux tableaux et non l'inverse.
Idem dans l'allocatememory qui dans l'exemple que je te donne, devrait-être crée à partir de l'exe et non de la Dll comme dans mon exemple qui est donc aussi une forme d'erreur.

Mais en réalité je ne comprend pas très bien ce à quoi tu veux arriver ? :(

- Créer un (ou des) tableau et le passer à la dll, qui éventuellement y ajouterais quelque chose ?
- Ou avoir la dll qui fournirais des données a un tableau pour te le donner ?
Ce qui est certain, c'est que tu dois fournir la bouteille... ==> Créer le, les tableaux dans le programme principal...
SVP... Alors explique en clair ! Moi, j'ai rien d'autre à faire que de me tenter de réactiver mes neurones perdus ! :(
Car par le biais de l'allocateMemory on peux y écrire ce que l'on veux...
La manière ou quoi dépend de nous, que cela vienne d'un tableau ou que cela aillent dans un tableau c'est la même chose !
Allocatememory => C'est un réservoir accessible des deux cotés...
D'ou mon incertitude ??? :(