Page 1 sur 2

Problemes mémoire pr KCC,c'est pas que dans la tete [Résolu]

Publié : jeu. 01/oct./2009 9:29
par Kwai chang caine
Bonjour la famille :D

Bon... toujours avec mon probleme de discution inter EXE et DLL :?
KCC il a essayer de bidouiller dans la mémoire comme CPL et SROD, il lui ont dit :roll:

Il a pondu un code a dormir dehors avec un ticket de logement :oops:
S'il vous plait, j'aimerais vous demander de ne pas essayer de changer la forme..
Car si il est si compliqué, c'est à cause des obligations de ce VB de malheur, et c'est suite a des dizaines d'essais infructueux que j'ai opté pour cette methode assez lourde :(
Afin que l'appel puisse se faire aussi bien de VB que de PB, et c'est ça qui est le plus dur :?

Donc, j'aimerais garder cette voie, si ça ne vous dérange pas trop, car elle m'a été conseillée par SROD, à force d'en essayer X qui ne me convenaient pas, ou ne marchaient pas :|
A moins que vous ayez une en 10 fois moins de lignes et qui fait papa/maman, alors la j'suis preneur :lol:
Ou bien si l'on peut simplifier en gardant cette forme :roll:

C'est à dire :

Travail de l'EXE
1/ Creation de "ArrayEXE", le tableau que je desire modifier
2/ Envoi de "ArrayEXE" à la DLL par son pointeur

Travail de la DLL
3/ Creation de "ArrayDLL", un nouveau tableau dans la DLL, afin de ne pas croiser les pointeurs DLL/EXE
4/ Copie de "ArrayExe" dans "ArrayDLL" (Rajout de separateurs de champs qui serviront plus tard lors de la mise en mémoire) dans mon cas c'est "|"
5/ Modifier "ArrayDLL" comme je l'entend, c'est le but de tout ce code (Addition et modification des lignes)
6/ Une fois la modif éffectuée, copier "ArrayDLL" dans un bloc memoire
7/ Renvoyer de la DLL le pointeur memoire du bloc

Travail de l'EXE
8/ Recuperer le pointeur du bloc mémoire provenant de la DLL
9/ Lire et splitter le bloc mémoire, et remplir/modifier le tableau "ArrayEXE" d'origine

Voila, je vous l'accorde, c'est pas simple, mais c'est une des methodes pour modifier un tableau d'EXE dans une DLL, sans melanger les pointeurs memoires, et risquer le crash, comme cela m'arrive depuis un mois :cry:
Et ce qui est le plus drole, c'est que je crois avoir choisi, la plus simples, :lol: ...si evidemment l'on veut, comme moi, se retrouver avec un tableau dans la DLL et pouvoir le travailler comme si c'etait celui de l'EXE, et sans passer par un fichier.

J'ai un probleme a la seconde liberation de la memoire :cry:
Et je trouve pas depuis toute la journée d'hier pourquoi....
Je pense que y'a quelque chose sur les mémoires que j'ai encore pas capté :oops:

Code : Tout sélectionner

; This procedure convert the pointer of array from EXE VB/PB to an array in the DLL
Procedure PointerArray2ArrayString(*strPtr.INTEGER, Array Array2Fill.s(1), ArraySize)
   
 Dim Array2Fill(ArraySize)
 Array2Fill(0) = Str(ArraySize) + "|" ; Write the lengh of array in line zero
  
 For i = 1 To ArraySize ; Start to 1 for not replace the lengh of array
  
  *strPtr + SizeOf(INTEGER)
  Donnee$ = PeekS(*strPtr\i, - 1, #PB_Unicode) + "|"
  
  If Trim(Donnee$) <> ""
   Array2Fill(i) = PeekS(*strPtr\i, - 1, #PB_Ascii) + "|"
  Else 
   Array2Fill(i) = Donnee$
  EndIf
     
 Next
   
EndProcedure

; This procedure convert an array string to a block of memory
Procedure ArrayString2PointerMemory(Array Array2Send.s(1))
 
 OffSet = 4 
 SizeArray2Send = ArraySize(Array2Send())
 Array2Send(0) = Trim(Str(SizeArray2Send))
 *IdMemory2 = AllocateMemory(SizeArray2Send)
 PokeS(*IdMemory2 + Offset, Array2Send(0) + "|")
 OffSet + Len(Array2Send(0) + "|")
 
 If *IdMemory2
  
  For i = 1 To SizeArray2Send
   PokeS(*IdMemory2 + Offset, Array2Send(i))
   OffSet + Len(Array2Send(i))
  Next
   
  PokeL(*IdMemory2, Offset)
  ProcedureReturn *IdMemory2
 
 Else
 
  ProcedureReturn #False
 
 EndIf
  
EndProcedure

; This is THE procedure for modify the array
; In this example i want replace the big word "Sentence" by little "Kcc" :-)
; And add two lines

ProcedureDLL ChangeNameAndAddLine(*strPtr.INTEGER, NameToChange.s, NameToReplace.s, ArraySize)

 Dim Array2Modify.s(0)
 PointerArray2ArrayString(*strPtr.INTEGER, Array2Modify(), ArraySize)
 
 For i = 1 To 5
  Array2Modify(i) = ReplaceString(Array2Modify(i), NameToChange, NameToReplace)
 Next
 
 OldSizeArray2Modify = ArraySize(Array2Modify())
 ReDim Array2Modify(ArraySize(Array2Modify()) + 2)
  
 For i = OldSizeArray2Modify + 1 To ArraySize(Array2Modify())
  Array2Modify(i) = "KCC add the line number " + Str(i) + "|"
 Next
 
 ProcedureReturn ArrayString2PointerMemory(Array2Modify())
 
EndProcedure

; This is a procedure for restore the array
; In this example i want replace the word "Kcc" by "Sentence"
; And delete two lines of the end

ProcedureDLL RestoreNameAndDeleteLine(*strPtr.INTEGER, NameToChange.s, NameToReplace.s, ArraySize)

 Dim Array2Modify.s(0)
 PointerArray2ArrayString(*strPtr.INTEGER, Array2Modify(), ArraySize)
 
 For i = 1 To 5
  Array2Modify(i) = ReplaceString(Array2Modify(i), NameToChange, NameToReplace)
 Next
 
 ReDim Array2Modify(ArraySize(Array2Modify()) - 2)
 ProcedureReturn ArrayString2PointerMemory(Array2Modify())
 
EndProcedure

; ******************************************************************************************************************
; ******************************************************************************************************************
; ******************************************************************************************************************
; ******************************************************************************************************************
;                                           SEPARATION EXE / DLL
; ******************************************************************************************************************
; ******************************************************************************************************************
; ******************************************************************************************************************

; This procedure convert the block memory to an array 
Procedure Memory2Array(*IdMemory, Array ArrayModified.s(1))
 
 SizeMemory = PeekL(*IdMemory)
 SizeArray = Val(PeekS(*IdMemory + 4))
 Dim ArrayModified.s(SizeArray)
 Line = 0
  
 For i = 0 To SizeMemory
  
  Char = PeekB(*IdMemory + 4 + i)

  If Char = 124
    Line + 1
   Continue
  EndIf 
  
  If Line > SizeArray
   Break
  EndIf 
   
  ArrayModified(Line) + Chr(Char)
    
 Next
 
 FreeMemory(*IdMemory)
 
EndProcedure
 
;                Create original array

Dim ArrayString.s(10)

For i = 1 To 10
 ArrayString(i) = "Sentence " + Str(i)
Next

;                  Modify the array four time

For o = 1 To 2
 
 *IdMemory = ChangeNameAndAddLine(ArrayString(), "Sentence", "Kcc", ArraySize(ArrayString()))
 Memory2Array(*IdMemory, ArrayString())
 
 For i = 0 To ArraySize(ArrayString())
  Debug ArrayString(i)
 Next
  
 *IdMemory = RestoreNameAndDeleteLine(ArrayString(), "Kcc", "Sentence", ArraySize(ArrayString()))
 Memory2Array(*IdMemory, ArrayString())
 
 For i = 0 To ArraySize(ArrayString())
  Debug ArrayString(i)
 Next
  
Next

Merci de votre aide et bonne journée

Re: Problemes de mémoire, pr KCC c'est dans la tete et l'IDE :-(

Publié : jeu. 01/oct./2009 10:21
par Kwai chang caine
J'ai modifié le code quatre fois, car j'ai déja trouvé quelques erreurs :oops:
Mais toujours le meme probleme de memoire à libérer

Re: Problemes de mémoire, pr KCC c'est dans la tete et l'IDE :-(

Publié : jeu. 01/oct./2009 11:31
par Backup
j'essaie de suivre ton problème depuis le début , et selon moi
et n'y vois pas là une agression de ma part, mais plutôt un constat. :)

je pense que tu pratique la masturbation intellectuel ! :)

j'entends par là , que tu cherche a faire un truc relativement simple
en un truc imbitable au possible

a tel point que finalement , j'arrive pas a comprendre ce que tu veux faire !

redéfinissons un peu les choses


pour moi une DLL c'est un ensemble de fonctions (procédures)
qui sont appelées en Esclave !

j'insiste sur ce fait , car (pour moi toujours) , une dll ne dois pas servir a recevoir /envoyer un tableau , mais plutôt a mettre au service du prg principal , le résultat de ses fonctions incluses , et rien d'autre ... :)
en aucun cas un Dll ne doit être vu comme un mini prg (comme tu as , je pense tendance a le faire )


si tu as un Prg V (en VB)
et un prg P (en pb)
et que tu veuille partager des contenus de tableau ,
il n'est pas convenable d'utiliser une dll pour ça .. :)
(a mon avis toujours...)

il existe d'autres procédés , qui sont adaptés a ce genre d'échange d'informations , même que ça s'appelle
la Mémoire Vive ( passage par la Ram )
ou encore, la mémoire de masse (passage par fichier)


ton vrais problème viens du fait que tu cherche utiliser des méthodes qui ne sont pas faite pour ça,
en utilisant une méthode qui (selon moi toujours ) relève de la fantasmagorie a propos des Dll...

lorsque tu comprendra qu'une Dll ne sert qu'a mettre a disposition
des traitements exécuté par des procedures , et QUE ça...
on aura gagné pas mal , je pense :)


dés que tu cherche a transmettre un tableau a une Dll, ou pire , a faire transmettre le contenu d'un tableau , par une dll , je pense que tu sort, de l'utilisation normale d'une dll ...
une Dll n'est pas un mini prg !

un tableau , est un ensemble de données !
et pour transmettre un ensemble de données , on utilise un fichier !

un fichier est un ensemble de données, qui peuvent etre un texte complet, une image, un ensemble de valeurs , bref tout ce qui comprends un nombre important de données !



j'ai souvent noté que bien des problèmes de programmation
peuvent etre résolu de façon simple , mais que leur auteurs
partent dans des solutions qui ressembles plus a du cirque qu'a de la programmation ....
souvent du d'ailleurs par un manque de Culture concernant l'histoire
de l'informatique, et donc de l'utilisation de tel ou tel composantes
(variables,constantes,fichiers,procedure,fonctions,sous prg,dll,etc ...)

mais bon.... c'etait juste mon avis ... :)

Re: Problemes de mémoire pr KCC, c'est pas que dans la tete :-(

Publié : jeu. 01/oct./2009 11:43
par djes
Je suis tout à fait d'accord avec Dobro. Ca rejoint un peu le débat de la philosophie Unix, où tous les programmes sont en ligne de commande. Les programmes sont là pour traiter des données. Sous Unix, ils reçoivent des données sur le canal d'entrée (sous forme de fichiers ou de pipe ou de frappe dans une console ou autre), traitent ces données, et les ressortent sur le canal de sortie. De cette façon on peut chaîner les programmes les uns avec les autres et faire des tas de traitements. Les interfaces graphiques sont pilotées de la même façon (ex les données envoyées par la souris le sont sur l'interface d'entrée, que cette souris soit sur ce poste ou sur un poste distant). C'est une méthode éprouvée de création d'un programme. Se lancer dans un truc d'interfaçage machin-bidule reposant sur des API figées, closed source et plus maintenues (comme celles de VB) n'amènera que frustration et grosses emmerdes à l'arrivée quand il faudra distribuer et utiliser le bébé, avec le support qui convient.

Re: Problemes de mémoire pr KCC, c'est pas que dans la tete :-(

Publié : jeu. 01/oct./2009 12:36
par Cls
Salut KCC,

Je ne reviendrais pas sur les posts précédents.

Ce que je ne comprends pas, c'est à quoi ça sert d'effectuer ces traitements dans la DLL (copie d'un tableau, ajout de lignes). Quel est l'objectif sous-jacent ?

Re: Problemes de mémoire pr KCC, c'est pas que dans la tete :-(

Publié : jeu. 01/oct./2009 12:43
par Kwai chang caine
Vous avez surement raison sur le principe.
Deja etant donné que vous avez autrement plus d'experience que moi, et en plus donc avez vu bien plus de choses depuis toutes ces années.

Le coup du fichier, evidemment c'est le plus simple, et donc ça marche, enfin en principe car avec VISTA et l'UAC...maintenant meme la creation d'un fichier est soumis a une autorisation :?
A mon boulot y'a des tonnes d'endroits ou je ne peux creer un fichier, a commencer parfois meme ou est mon propre programme, car pour l'installer j'ai demandé une autorisation, et apres ce bouffon il me la redemande pour creer un fichier....

En fin de compte tout ça aurait été simple, si je passais le tableau en string, car une DLL peut etre bien la, pour recevoir un parametre en faire quelque chose et le retourner ?????
C'est une de ces fonctions...enfin j'espere :oops:
Ou bien d'aller chercher quelque chose...comme par exemple une valeur quelconque du systeme, etc....

La ou je te rejoint completement DOBRO, c'est que je demande a une DLL de me retourner un tableau au lieu d'une variable.
C'est peut etre pas commun, mais c'est pas non plus insurmontable, car un tableau c'est ni plus ni moins que X variables.
Le seul probleme pour untableau de string c'est qu'elles sont disséminées dans la mémoire, et qu'il faut lacher le chien pour ramener les brebis à la ferme :D

Tu as raison surement de dire que ce que je demande est pas "habituel" puisque je trouve pas "d'equivalent"
Mais par contre, je ne suis pas sur que ce soit pas possible, ou bien pas dans ses attributions :roll:

Aparement la communication de données, objets EXE/DLL est une chose commune pour CROSOFT.
Il y a meme soi-disant des centaines de methodes, dont 99 dont je ne sais pas me servir et dont je n'ai meme pas compris le titre :oops: PIPE, MUTEX, PROTOTYPE, BLOC MEMOIRE, VARIABLE, PARTAGE MEMOIRE etc ..
Et dans chacune de ces methodes surement une tonne de variantes....

Bref, en fin de compte, ce qui me durcit la tache, c'est de vouloir que la meme procedure soit utilisable par VB et PB
Car quand j'avais trouvé avec un , c'est l'autre qui sait pas faire, etc ...
Rien qu'a l'idée de faire un PEEK en VB...je me regale d'avance :lol:

Apparement cette methode est lourde, car cela fait creer un tableau de chaque coté, mais elle devrait, enfin je dit bien, devrait etre utilisable des 2 cotés...enfin j'espere, ...si j'arrive a lire la memoire en VB :roll:

Voila, alors je reconnais mille fois que quand on voit ce code, pour transferer 4 données, y'a quoi pouffer de rire :lol:
Mais si j'arrive a faire passer des tableaux , comme on fait passer communement des variables tous les jours dans les DLL.
Et bien cela devrait me faire gagner des centaines de ligne de code, peut etre plus.
Car chacun de mes programmes qu'ils soit PB, VB et peut etre si les dieux m'entendent C++ plus tard, pourront utiliser TOUTES les fonctions de mes DLL, et il me restera plus qu'a faire la GUI, et hop....a la maniere des grosses DLL de windows, plus jamais je ne reecrirais la meme fonction :D

C'est pour ça que pour moi c'est tres important, car c'est une des pieces maitresse et centrale de TOUS mes programmes.
Je voudrait tout construire autour de ça....alors le mieux ce serait que je ne me gourre pas :lol:
D'ailleur j'ai basé beaucoup de mes prog sur le passage des tableaux et ça marchait super bien, car je le passait qu'une fois.
Jusqu'au jour ou il y a un mois, j'ai appelé 2 fois de suite la meme procedure....et la les bras me sont tombé par terre, car je suis entré dans l'enfer de la gestion des pointeurs mémoire...et pour moi c'est pas du gateau.

Donc tous mes programmes attendent de pouvoir passer deux ou plusieurd fois, un tableau gros ou petit et l'aventure continue... :D

En fin de compte c'est quand meme pas l'amerique que je cherche a obtenir ??? :wink:

Re: Problemes de mémoire pr KCC, c'est pas que dans la tete :-(

Publié : jeu. 01/oct./2009 12:47
par Kwai chang caine
Cls a écrit :Salut KCC,
Je ne reviendrais pas sur les posts précédents.
Ce que je ne comprends pas, c'est à quoi ça sert d'effectuer ces traitements dans la DLL (copie d'un tableau, ajout de lignes). Quel est l'objectif sous-jacent ?
Bonjour CLS

Comme je l'ai expliqué au dessus mais nous avons posté ensemble.
C'est pour centraliser le maximum de fonctions dans les DLL, et ne laisser a VB et PB que les interfaces graphiques.
Un gain de temps enorme pour la programmation, car j'utilise toujours les memes styles de fonctions pour mon boulot.

J'ai deja créé une bonne centaine de procedure en DLL, que j'utilise quotidiennement.
C'est genial a la maniere des API....je veux l'arboresence...hop j'ai une KCCPI :D

Exemple

Code : Tout sélectionner

Tablo() = ScanRep(Chemin, ModeDeRetour, Filtre)
Voila mon bon CLS :wink:
MAis pour ça ...il faut bien que je le ramene ce put....de tableau de m.... à la c.... pour l'afficher dans ma GUI :? :? :lol: :lol: :lol:
Ca fait un mois, qu'il veut pas rentrer a la maison, normal c'est UNE dll...alors il prefere fricoter avec elle que revenir dans UN programme :?
Decidement deja petit j'avais un tres gros probleme avec les tableau a l'ecole...quand il fallait y aller....je me faisait dessus :oops:
Mais cette fois il m'ennerve tellement que j'ai envie de lui faire dessus...c'est pas la meme chose :?

Re: Problemes de mémoire pr KCC, c'est pas que dans la tete :-(

Publié : jeu. 01/oct./2009 13:37
par Cls
D'accord je vois.

Avant de faire quoi que ce soit, il faut savoir pourquoi ça plante. Je vois 2 choses :
1. l'adresse mémoire est déjà utilisée => ça plante, normal
2. 2 bouts de codes essayent d'accéder simultanément à ton tableau => problème d'accès concurrents, ça patate ! (Normal aussi)

Pour le problème 1, si tes réservations de mémoires sont faites par les programmes appelant la DLL, il n'y a aucune raison que ça arrive. Reste alors le point 2.

Je te conseille de protéger tous tes accès à la mémoire avec des Mutex ou des sémaphores (dans ta DLL et dans ton programme). C'est généralement ce qui pose problème quand on a un "accès mémoire invalide", ou un truc dans le genre.

Pour l'heure, je n'ai pas le temps de regarder ton code mais je vais essayer de jeter un oeil.

Re: Problemes de mémoire pr KCC, c'est pas que dans la tete :-(

Publié : jeu. 01/oct./2009 13:56
par Kwai chang caine
Merci beaucoup CLS 8)

En fait pour l'instant, je suis dans les essais de souflerie :lol:
J'ai encore meme pas exporté la DLL :oops:

Le code plante dans le meme programme
Tu as raison, c'est un mauvais acces a la memoire qui fait planter

Je viens de trouver quelque chose qui arrete le plantage
Dans la procedure "ArrayString2PointerMemory(Array Array2Send.s(1))"
Si j'augmente l'allocation de memoire de 400 par exemple..ça marche 8O

Code : Tout sélectionner

*IdMemory2 = AllocateMemory(SizeArray2Send + 400)
Mais je comprend pas pourquoi :(

Et KCC il aime bien comprendre, car non seulement y comprend jamais les codes des autres ....mais y comprend meme pas les siens :cry:

Pourtant c'est un tableau ASCII, donc 1 octet par ligne de tableau ça devrait suffir, non ??
En fait mon tableau est sous cette forme en memoire

4 octets pour un long = Longueur du bloc de memoire
1 octet pour la ligne (0) qui contient la longueur du tableau
1 octet par ligne de tableau

Donc si le tableau est de 10, ne devrais je pas réserver 10 + 1 + 4 octets ???? :roll:

Re: Problemes de mémoire pr KCC, c'est pas que dans la tete :-(

Publié : jeu. 01/oct./2009 14:08
par Anonyme2
Essaye aussi la procedure de Fred pour la corruption de mémoire.

Je te renvoie à l'article du blog PB ici (en anglais ...) sur la corruption mémoire, excellent article avec une procédure permettant de trouver ses erreurs lorsque l'entête mémoire système a été écrasée par les données écrites.

http://www.purebasic.fr/blog/?m=200810

Pour l'avoir utilisée, elle fonctionne parfaitement et m'a permis de trouver mes erreurs sur la mémoire à plusieurs reprises. Sans cette procédure, je chercherais encore, parfois l'erreur est bien avant.

Si tu ne sais pas comment faire, je t'aiderais à l'utiliser mais cherche un peu :mrgreen:

Mon bon KCC, au lieu d'écrire

Code : Tout sélectionner

FreeMemory(*IdMemory) 
tu devrais tester au moins tester que le pointeur est non nul, juste par précaution. Idem à l'allocation de mémoire, tu dois absolument tester si elle a réussie.

Sinon, VB utilise l'unicode ? as-tu essayé de compiler en unicode la dll et les exe ?
Si tu tentes d'écrire plus de caractères que la mémoire allouée, il me semble que les données de MS concernant la mémoire sont écrasées. Cela doit être expliqué dans l'article du blog si je me souviens bien.

Re: Problemes de mémoire pr KCC, c'est pas que dans la tete :-(

Publié : jeu. 01/oct./2009 14:20
par Cls
J'ai jeté un petit coup d'oeil. Attention faut s'accrocher, dis moi !!

Bon j'ai compris pourquoi la mémoire n'est pas assez importante.
Le fameux

Code : Tout sélectionner

*IdMemory2 = AllocateMemory(SizeArray2Send)
En effet, SizeArray2Send contient le nombre d'élément du tableau (soit 10 dans ton cas). Or ce qui nous intéresse, c'est la taille des données (en gros la taille du texte contenu dans le tableau). Cette taille varie selon le contenu (ici elle n'est pas très importante "Sentence X" sur chaque ligne).

Tu peux utiliser ceci pour calculer la taille totale du tableau :

Code : Tout sélectionner

MemorySize2Send = 0
  For i = 1 To SizeArray2Send
    MemorySize2Send + Len(Array2Send(i) + "|") 
  Next

*IdMemory2 = AllocateMemory(MemorySize2Send)

Re: Problemes de mémoire pr KCC, c'est pas que dans la tete :-(

Publié : jeu. 01/oct./2009 14:30
par Kwai chang caine
Merci DENIS 8)

KCC y cherche ..y cherche...
Il a le groin plein de terre depuis un mois
Image
Y va essayer de comprendre pour la mémoire :roll:

J'avais cherché si il existait un IsMemory, mais apparement d'apres FREAK c'est pas au gout du jour :cry:
C'est vrai c'est pas pratique...ça serait cool d'avoir un utilitaire qui permet de visionner la memoire :roll:

Pour les protections..c'est promis je le ferais :wink:

Re: Problemes de mémoire pr KCC, c'est pas que dans la tete :-(

Publié : jeu. 01/oct./2009 14:33
par Kwai chang caine
Cls a écrit :J'ai jeté un petit coup d'oeil. Attention faut s'accrocher, dis moi !!
Bon j'ai compris pourquoi la mémoire n'est pas assez importante.
Le fameux

Code : Tout sélectionner

*IdMemory2 = AllocateMemory(SizeArray2Send)
En effet, SizeArray2Send contient le nombre d'élément du tableau (soit 10 dans ton cas). Or ce qui nous intéresse, c'est la taille des données (en gros la taille du texte contenu dans le tableau). Cette taille varie selon le contenu (ici elle n'est pas très importante "Sentence X" sur chaque ligne).
Tu peux utiliser ceci pour calculer la taille totale du tableau :

Code : Tout sélectionner

MemorySize2Send = 0
  For i = 1 To SizeArray2Send
    MemorySize2Send + Len(Array2Send(i) + "|") 
  Next
*IdMemory2 = AllocateMemory(MemorySize2Send)
Cool...j'me melange les pingoinces entre les pointeurs et les longueurs de variable...
Je vais regarder ça ....super merci CLS :D

Re: Problemes de mémoire pr KCC, c'est pas que dans la tete :-(

Publié : jeu. 01/oct./2009 15:04
par Kwai chang caine
Ouuuuaaaouuuhhhh !!!!!
Tu as trouvé CLS :D
Image

Apparement, ça marche y me semblait bien que y'avais une histoire de allocate pas assez grand.
Pour une fois que KCC, il essaie de faire des economies :oops:

Puis c'est comme tout, ça fait 15 heures que j'ai le nez sur ce code 8O
On relis 100 fois les memes lignes et on resonne 100 fois comme une cloche au meme endroit :twisted:

Pour la complexité, en fait c'est comme tous les appartements des autres ...c'est toujours plus le bordel que dans le siens :lol: :lol:

Au final, y'auras juste :

Dans la DLL

Code : Tout sélectionner

Procedure PointerArray2ArrayString(*strPtr.INTEGER, Array Array2Fill.s(1), ArraySize)
Procedure ArrayString2PointerMemory(Array Array2Send.s(1))
La premiere pour recuperer le pointeur et le copier dans un tableau
La seconde une fois le tableau travaillé pour le rendre a cesar ...pion :mrgreen:

Dans l'EXE

Code : Tout sélectionner

Procedure Memory2Array(*IdMemory, Array ArrayModified.s(1))
Juste celle la pour lire la mémoire.
Je me marre d'avance, car ma prochaine mission c'est de faire pareil en VB :?

Et avec ces 3 petites procedures..on peut se passer les tableaux de l'un à l'autre...comme les legionnaires les gonzesses :D

Voila voila...je vous remercie tous de votre aide, et votre interet
Et encore merci a toi CLS (L'oeil du tigre) qui a trouvé la ou j'ai péché 8)

Je vous souhaite une excelente journée a tous
Et tanpis pour vous .....je vous dis a bientot pour de nouvelles aventures :D

Re: Problemes de mémoire pr KCC, c'est pas que dans la tete :-(

Publié : jeu. 01/oct./2009 15:20
par GeBonet
Ben... Comme il y a 10 jours
Comme Dobro et Djes je pense que tout serais tellement plus simple à passer par le disque...

Mais voilà, c'est KCC, alors quand je reprend tes conditions qui sont :

C'est à dire :
Travail de l'EXE ICI C'est l'EXE ... On lit les data, mais en fait n'importe quel autre chose
sous forme string.... et je fait donc ton point 1 et 2 et même plus puisque je ne me limite pas à un caractère mais des chaines....
Et j'envois le POINTEUR à la DLL Donc première partie l'EXE .... Pour :
1/ Creation de "ArrayEXE", le tableau que je desire modifier
2/ Envoi de "ArrayEXE" à la DLL par son pointeur
l'envois et le retour de DLL ....

Code : Tout sélectionner

; **************************************************************************************
;  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é..... 
; ****************************************************************************************
; Note: Depuis 4.40b1 vous ne pouvez pas passer des 'entiers' en utilisant CallFunctionFast (). 
;           Si vous voulez passer des chaînes directement comme paramètres, vous devez ajouter le caractère '@' pour passer l'adresse. 
;
; Exemples :
;
; non-unicode :  Fonctionne avec 4.31 mais pas avec 4.40b1
;                        CallFunctionFast(p_messageboxa,0,@"hello world 1",@"test",0)
; -------------------------------------
; non-unicode : Fonctionne avec 4.31 Ainsi qu'avec 4.40b1
;                        CallFunctionFast(p_messageboxa,0,"hello world 1","test",0)
; -------------------------------------------------------------------------------------------------------
; C'est à dire :
;
; Travail de l'EXE                                ICI C'est l'EXE ...     On lit les data, mais en fait n'importe quel autre chose
;                                                          sous forme string.... et je fait donc ton point 1 et 2 et même plus puisque 
;                                                                                            je ne me limite pas à un caractère mais des chaines....
;                                                          Et j'envois le POINTEUR à la DLL
; ------------------------------------------------------------------------------
;  ------------------------------------------------------------------------------
#Dim1=20 ;          ------------->>>> Ici on peux monter jusqu'au nombre de DATA soit 70...
Global Dim ArrayA.s(#Dim1)       ; Ce sera une 4ième forme que je te présente 
;  -----------------------------------------------                                                     
;       Programme Client de la DLL 
;  -----------------------------------------------
#Bibliotheque=0 
OpenLibrary(#Bibliotheque,"Dll_AvecTable.dll")

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)  ; ,*Pointeur
    ;           
    ;**************************************************************************  
    ; RETOUR DE LA DLL : ICI je récupère le pointeur du tableau de la DLL qui est le pointeur
    ;                                       du tableau crée dans la DLL et je peux lire mon tableau et celui de la dll
    ;                                       Je fais donc ce que demande ton point 8 et 9.... 
    ;                                       ET montre les résultat du travaille dans DLL
    ; 
    ; Tu demande CECI : ET C'EST EXACTEMENT CE QUE JE FAIS ??? 
    ; ---------------------------------------------------------------------------------------------------------------------
    ; Travail de l'EXE
    ; ---------------------
    ; 8/ Recuperer le pointeur du bloc mémoire provenant de la DLL
    ; 9/ Lire et splitter le bloc mémoire, et remplir/modifier le tableau "ArrayEXE" d'origine
    ; ---------------------------------------------------------------------------------------------------------------------
    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
; ************************************************************  
Puis la DLL qui dans ce cas travaille bien avec un Autre tableau à elle qui le cas échéant pourrait
avoir un ReDim... Mais il faudrait pour cela renvoyer aussi l'augmentation du tableau...
Ce qui n'est pas un problème si tu conviens que la dernière donnée du tableau doit-être un
mots définit... Alors tu augmente aussi le retour d'un ligne tant que tu n'as pas ce mots de retour !

Code : Tout sélectionner

; -------------------------------------------------------------------------------------------------------
;  Ce que fait cette DLL 
;
;  1- Elle crée un tableau ArrayB.s(Taille) (donnée par l'appelant)
;  2- Elle lit un tableau ArrayA.s(n) envoyé par l'appelant 
;  3- Elle copie le contenus de A vers B .... Et Affiche B qui est de la DLL
;  4- Elle produit un trabvaille qui est d'inverser les mots de SON tableau 
;  5- ET elle renvois l'adresse de son tableau a elle qui sera lus dans l'appelant...
;      C'est bien ce que tu veux ??? 
; 
; ************************************************************  
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(@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à, je réponds complètement à tes conditions...
Ou alors il y a vraiment quelque chose qui m'échappe...
Voilà, voilà... 8)