KCC y veut deux tableaux...et ben il en a qu'un [Resolu]

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

KCC y veut deux tableaux...et ben il en a qu'un [Resolu]

Message par Kwai chang caine »

Bonjour à tous

J'suis dégouté...j'y comprend decidement rien a cette mémoire. :cry:
J'arrive aussi bien a gerer la mienne que celle de mon PC :oops:

Voila.... j'ultilise depuis longtemps une procedure dans une DLL, qui me retourne l'adresse d'un tablo de string et depuis ce temps KCC il etait heureux comme un homme au milieu d'un harem :D
Et en plus, drolement fier, parce qu'il croyait avoir tout compris de ce qui se passe dans la mémoire de sa machine :D

Et avant hier, KCC il appelle deux fois de suite la dite procedure, et la ....patatrac, adieu veaux, vaches, cochons......toute la fierté de KCC elle est retournée à un endroit qu'elle n'aurait jamais du quitter.....c'est à dire, dans ses pompes :cry:

Parce que j'appelle donc 2 fois cette procedure et essaye de charger a chaque fois le retour du tableau de la DLL dans un tablo de l'exe different.

En debug ça marche, mais quand je retourne voir le premier tableau et ben ou au mieux il a été écrasé par le second....ou bien j'obtiens des caracteres qui seraient du plus bel effet dans la chambre de RAMSES II 8O

J'ai posé la question sur le US et XOMBIE m'a dit que je reutilise le meme pointeur de tableau, ce a quoi j'ai répondu que oui puisque j'appelle la DLL ...elle charge un tableau propre a elle, et renvoi son adresse une fois plein.
Je recupere cette adresse et je copie le tableau de la DLL dans mon 1er tableau de l'exe...jusqu'a la...tout "benne" :D

Mais quand je rapelle, tout de suite derriere, la meme DLL et la meme procedure, elle redimensionne son tablo pour etre sur de l'effacer, et elle charge une autre valeur, puis renvoi a nouveau l'adresse de son tableau.
A nouveau, je recupere l'adresse et copie un second tableau dans l'exe grace à elle.

Et c'est la, que y'a ........(excusez moi l'expression quelque peu cavaliere)........ couille dans le potage :?
Le second tableau de l'exe viens ecraser le premier 8O

Alors la ....... je reste dans voix, ça fait deux jours que je cherche tout seul devant mon ecran...mais la je crois que y'a un "miasme" qui m'echappe :oops:

Si quelqu'un pouvait allumer une bougie dans cette penombre qui est desormais mienne :cry:

Voici le fruit de ma souffrance :

L'EXE

Code : Tout sélectionner

Dim ArrayA.s(0) 

OpenLibrary(0,"dll.dll") 

ArrayA() = CallFunction(0, "CreateArray", "a") 

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

Dim ArrayB.s(0)  
ArrayB() = CallFunction(0, "CreateArray", "b") 

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

CallDebugger
La DLL

Code : Tout sélectionner

ProcedureDLL.l CreateArray(Lettre$) 
  
 Shared Passage, xx 
      
 Passage + 1 
    
 If Passage = 1 
  Global Dim ArrayDll.s(100000) 
 EndIf 
  
 For x = 1 To 5 
  xx + 1 
  ArrayDll(xx) = RSet("", xx, Lettre$) 
 Next 
  
 If Passage = 1 
  CreateArray(Lettre$) 
  ReDim ArrayDll.s(xx) 
  Passage = 0 
  xx = 0 
 EndIf 
    
 ProcedureReturn @ArrayDll() 
    
EndProcedure
Je vous remercie et vous souhaite une bonne journée
Dernière modification par Kwai chang caine le mer. 05/août/2009 12:38, modifié 1 fois.
Anonyme

Message par Anonyme »

Attention , à prendre avec des pincettes se qui suit.


Il me semble , que le tableau que tu alloues dans ta procedure de la dll
n'est viable que pour cette dite procédure. En gros , c'est logique que ca marche une fois puisque tu as le pointeur d'une variable qui n'est plus valide ( donc pour ton programme , ce champ de mémoire est "libre" ) le second appel écrase alors une partie ou la totalité de cette mémoire , ce qui peut provoqué des bugs sur plusieurs appel.

la solution est je pense :

AllocateMemory() / qui est valide même en dehors d'une procedure.

Code : Tout sélectionner

ProcedureDLL.l CreateArray(Lettre$)  
  
 Shared Passage, xx  
    
 Passage + 1  
   
 If Passage = 1  
 Global Dim ArrayDll.s(100000)  
 EndIf  
  
 For x = 1 To 5  
 xx + 1  
 ArrayDll(xx) = RSet("", xx, Lettre$)  
 Next  
  
 If Passage = 1  
 CreateArray(Lettre$)  
 ReDim ArrayDll.s(xx)  
 Passage = 0  
 xx = 0  
 EndIf  
   
 ProcedureReturn @ArrayDll()  
   
EndProcedure

Pour moi ta procédure est fausse.

Code : Tout sélectionner

 If Passage = 1  
 CreateArray(Lettre$)  
 ReDim ArrayDll.s(xx)  
 Passage = 0  
 xx = 0  
 EndIf  
Passage sera toujours = à 1 dans ta procédure. pas la peine de testé donc. il sert même à rien d'ailleurs.
tu alloue 100000 de taille , je n'ai que 10 éléments en sortie...
je vais regardé ca.
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Message par Kwai chang caine »

Merci beaucoup de ta rapidité CPL 8)
Comme dab le soldat ne dort que d'un oeil :wink:
Passage sera toujours = à 1 dans ta procédure. pas la peine de testé donc. il sert même à rien d'ailleurs.
Pas tout a fait, car si tu remarque le

Code : Tout sélectionner

If Passage = 1 
  CreateArray(Lettre$) 

je reappelle cette meme procedure à l'interieur d'elle meme.
Donc au second passage "Passage" est egal a 2 donc il ne redimensionne pas le tableau.

Comme dab j'ai essayé de garder la structure de ma DLL sans vous en donner des pages à lire.
Alors ne me demande pas pourquoi je reappelle la procedure, car dans cette exemple simplifié y'a aucun interet, je le sais.
Dans ma DLL, elle fait une recherche recursive donc elle s'apelle elle meme.
J'ai bien fait attention de recreer le meme probleme au plus simple, afin que tu te retrouve dans la meme config que ma grosse DLL :D
Surtout que je sais que quand on est dans une procedure au niveau memoire c'est tout a fait different, alors quand on fait du recursif...je me mefie encore plus de la gestion de memoire :roll:
tu alloue 100000 de taille , je n'ai que 10 éléments en sortie...
Oui encore une fois ma DLL elle a besoin de cette taille car elle scanne tout un DD parfois, evidemment dans cet exemple de quelques ligne ça parait ridicule.
Mais c'est toujours dans un soucis de te mettre dans la meme config, on sait jamais...peut etre que y peut y avoir des depassements de memoire ou je ne sais quoi......
Alors, je prefere garder les points "dangereux" (Grosse allocation, Recursivité, etc...) dans l'exemple, afin que si vous me trouvez une solution, elle marche dans ma DLL :D

Encore merci de te pencher sur mon berceau 8)
gnozal
Messages : 832
Inscription : mar. 07/déc./2004 17:35
Localisation : France
Contact :

Message par gnozal »

A mon avis :

Code : Tout sélectionner

;
; Un tableau de chaînes est un tableau de pointeurs (vers des chaînes) et pas une succession de chaînes.
;
Dim a$(2)
;
a$(0) = "Kcc 1ere chaîne"
a$(1) = "KCc 2eme chaîne"
a$(2) = "KCC 3eme chaîne"
;
*a = @a$() ; pointeur vers tableau a$()
Debug "Le tableau est en " + Str(*a)
*a1 = PeekL(*a) ; pointeur vers chaîne a$(0)
Debug "La chaîne 1 est en " + Str(*a1)
*a2 = PeekL(*a + SizeOf(Integer)) ; pointeur vers chaîne a$(1)
Debug "La chaîne 2 est en " + Str(*a2)
*a3 = PeekL(*a + SizeOf(Integer) * 2) ; pointeur vers chaîne a$(2)
Debug "La chaîne 3 est en " + Str(*a3)
;
Debug "Les chaînes : "
Debug PeekS(*a1) 
Debug PeekS(*a2)
Debug PeekS(*a3)
;
; Quand tu fais ArrayA() = CallFunction(0, "CreateArray", "a"), il y a copie des pointeurs _mais_ pas des chaînes.
;
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Message par Kwai chang caine »

Bonjour GNOZAL, merci aussi de repondre a mon appel de detresse 8)

Je vais regarder et essayer de comprendre ce que tu viens de me dire :roll:
Mais ce que je comprend tout de suite "ipso-facto" c'est que KCC y s'est encore mis dans la "oumfa" jusqu'au coup :cry:

Donc si je comprend a peu pres, c'est pour ça que j'ai des moitié de texte et du payrus sur tout l'ecran.

Car je copie les pointeurs !!! :roll:
Mais alors comment copier le tableau ???

Nadine boudin...mais pourquoi, a chaque fois que je veux renifler une fleur, je fourre toujours mon groin dans une fourmillere :?
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Message par Kwai chang caine »

Deja je viens de comprendre quelque chose qu'a rien a voir avec la choucroute, ou presque c'est que :

Code : Tout sélectionner

*a = @a$() ; pointeur vers tableau a$() 
a = @a$() ; pointeur vers tableau a$() 
Debug "Le tableau est en " + Str(*a) 
Debug "Le tableau est en " + Str(@a$()) 
Debug "Le tableau est en " + Str(a) 
Les trois resultats sont les memes......donc si je pose 1 et je retiens 2.....dans ce cas :

Code : Tout sélectionner

*a = @a$() = a =  pointeur vers tableau a$() 
Donc on peut ecrire une adresse pointeur soit par "*Machin" soit par "Machin" soit par "@Machin()" dans ce cas la evidemment.

Moi je n'arrivais pas vraiment a comprendre la difference entre *a et @a
@a c'est l'adresse pointeur de la variable a
*a c'est une variable qui contiens l'adresse et qui est formaté selon le processeur en 4 ou 8 octets (J'ai pas trouvé ça tout seul...c'est FREDO il a dit) :D

Donc pour "recapépéter" on est pas obligé de mettre "l'obélisque" devant le "A" si on fait bien attention que la variable fait 4 octet pour un X32
J'ai juste au moins la :D
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

pour simplifier le truc
moi lorsque j'ai des valeurs ou autre chaines a passer d' un endoit a un autre
genre dll a prg, ou l'inverse , et que ça me prends la tete

je m'emmerde pas , je copie ce que je veux faire passer dans un fichier
et c'est ce fichier, que je relis ,puis que j'efface, comme ça tu te prend pas la courge !

tu peux transmettre tout un tableau complet, et meme beaucoup plus .. ;)


de nos jour le passage par fichiers n'est plus considéré comme "lent"
avec les HD que nous avons maintenant , on peux se permettre ça !
on est plus au temps ou l'on enregistrai nos donées sur des cassettes audio :lol:

d'ailleurs le system d'exploitation utilise ce principe pour ses propres besoin
ça s'appelle la base de registre :)

le principe des bases de données c'est ça aussi ;)

de plus si tu prends soin de bien effacer ton fichier des que tu t'en sert plus
ben pas de problèmes ;)

pourquoi faire compliqué lorsqu'on peux faire tres simple ;) ??
gnozal
Messages : 832
Inscription : mar. 07/déc./2004 17:35
Localisation : France
Contact :

Message par gnozal »

Kwai chang caine a écrit :Car je copie les pointeurs !!! :roll:
Mais alors comment copier le tableau ???
Pour les tableaux de chaînes, pas possible en un bloc, puisque si les pointeurs se suivent, les chaînes elles peuvent être n'importe où en mémoire.
On peut les passer une par une par exemple.
Pseudo code :

Code : Tout sélectionner

TailleTableau = KCC_CreateArray("a") ; renvoie la taille du tableau ou -1 si échec
If TailleTableau <> -1
  Dim Array.s(TailleTableau)
  For i = 0 To TailleTableau - 1
    Array(i) = KCC_GetArrayElement(i) ; transfère le tableau chaîne par chaîne
  Next
EndIf
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Message par Kwai chang caine »

Bonjour DOBRO.

Oui tu as raison ... pourquoi faire compliqué...

Mais bon dans ce cas, ça m'aide a comprendre pour les pointeurs et tout le toutim.
Parce que le reve de KCC il est dans son nom.....c'est de KC du C :lol:

Alors comme je sais que de peter plus haut que son cul, ne tue pas, autrement je serais presque tout seul au boulot...alors je reve....

Et puis, j'aime pas trop les fichiers, et en plus j'y pense, bien souvent l'utilisateur n'a pas toujours les droits sur les repertoires...donc ça me plante mes progs.
Donc voila....mais si personne ne trouve une solution...bah il restera la bidouille

Merci de ton intervention DOBRO 8)
gnozal
Messages : 832
Inscription : mar. 07/déc./2004 17:35
Localisation : France
Contact :

Message par gnozal »

Kwai chang caine a écrit :Et puis, j'aime pas trop les fichiers, et en plus j'y pense, bien souvent l'utilisateur n'a pas toujours les droits sur les repertoires...donc ça me plante mes progs.
Il y a au moins le répertoire temporaire, qu'on obtient par GetTemporaryDirectory().
Tout le monde y a accès.
Cls
Messages : 620
Inscription : mer. 22/juin/2005 8:51
Localisation : Nantes

Message par Cls »

Je sais que je radote (:oops:) mais il y a toujours cette solution : http://www.purebasic.fr/french/viewtopi ... ht=mapping
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Message par Kwai chang caine »

gnozal a écrit :
Kwai chang caine a écrit :Car je copie les pointeurs !!! :roll:
Mais alors comment copier le tableau ???
Pour les tableaux de chaînes, pas possible en un bloc, puisque si les pointeurs se suivent, les chaînes elles peuvent être n'importe où en mémoire.
On peut les passer une par une par exemple.
Pseudo code :

Code : Tout sélectionner

TailleTableau = KCC_CreateArray("a") ; renvoie la taille du tableau ou -1 si échec
If TailleTableau <> -1
  Dim Array.s(TailleTableau)
  For i = 0 To TailleTableau - 1
    Array(i) = KCC_GetArrayElement(i) ; transfère le tableau chaîne par chaîne
  Next
EndIf
Ok je commence a comprendre pour le retour de tableau complet. 8)

Mais ce qui est bizzare, c'est que admettons que la premiere fois ma DLL me retourne un tableau de pointeurs qui correspond a chacune des strings du tableau.....et la ça marche :D

La seconde fois, le tableau se reinitialise avec le global, donc il est aussi pure (basic :lol:) que le doux jesus qui viens de naitre :D
Il renvois a nouveau la liste des pointeurs des nouvelles strings......alors pourquoi a la seconde fois on peut pas recuperer cette liste comme a la premiere ???? :roll:

C'est une histoire de "guedin" cette histoire ...... :?
gnozal
Messages : 832
Inscription : mar. 07/déc./2004 17:35
Localisation : France
Contact :

Message par gnozal »

La seconde fois, le tableau étant réinitialisé, les pointeurs transmis la 1ère fois ne sont plus valides.
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Message par Kwai chang caine »

Cls a écrit :Je sais que je radote (:oops:) mais il y a toujours cette solution : http://www.purebasic.fr/french/viewtopi ... ht=mapping
Bonjour mon bon CLS :D

Ah la pas du tout...c'est toujours un plaisir de parler avec toi, meme si a chaque fois tu donne la meme solution :lol: :lol: :lol:

Non je rigole....en fait ça me fait un peu peur le partage memoire, j'y comprend encore moins que les retour procedure.
Et puis je trouve que c'est un peu de l'artillerie lourde pour retourner un resultat de procedure :roll:
Certe bien moins lourde que la methode de fichier, mais quand meme compliqué pour un novice comme moi :oops:

Mais c'est vrai que si on a a échanger des informations constament entre deux appli, alors la c'est du velour 8)
Mais encore une fois si on ne trouve pas ...ça fait une solution de plus :wink:
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Message par Kwai chang caine »

gnozal a écrit :La seconde fois, le tableau étant réinitialisé, les pointeurs transmis la 1ère fois ne sont plus valides.
D'accord mais le second retour, suite au second appel, est bien un retour des nouveaux pointeurs du nouveau tableau, non ???

Premier appel

Code : Tout sélectionner

ArrayA() = CallFunction(0, "CreateArray", "a") 
Second appel

Code : Tout sélectionner

ArrayB() = CallFunction(0, "CreateArray", "b") 
Je dis une connerie la ?? :oops:
Répondre