FORUM DE DISCUSSION SUR LE LANGAGE PANORAMIC

Développement d'applications avec le langage Panoramic
 
AccueilAccueil  FAQFAQ  RechercherRechercher  S'enregistrerS'enregistrer  MembresMembres  GroupesGroupes  Connexion  
Derniers sujets
» Planétarium virtuel.
par Pedro Alvarez Sam 21 Juil 2018 - 16:57

» Roues dentées
par jean_debord Sam 21 Juil 2018 - 10:40

» Attention arnaque !
par mindstorm Jeu 19 Juil 2018 - 19:18

» Qui fait quoi ?
par silverman Mer 18 Juil 2018 - 15:21

» ITEM_SELECT N,L pour synedit
par silverman Mer 18 Juil 2018 - 15:20

» Boussole
par jean_debord Mer 18 Juil 2018 - 11:06

» Roue à n faces
par Marc Dim 15 Juil 2018 - 22:16

» Exemple d'une nouvelle version d'un GRID
par Jean Claude Ven 13 Juil 2018 - 10:32

» Une simple question
par Oscaribout Sam 7 Juil 2018 - 23:20

» BUG sur l'objet TAB
par Jack Sam 7 Juil 2018 - 21:12

» Monopoly moderne
par jjn4 Sam 7 Juil 2018 - 15:06

» Récapitulatif ludothèque panoramic jjn4
par jjn4 Ven 6 Juil 2018 - 17:41

» Lignes ondulées
par JL35 Ven 6 Juil 2018 - 17:39

» bug off_activate 0 : sans d'effet
par silverman Ven 6 Juil 2018 - 13:02

» Position des objets d'un conteneur dans FBPano et Panoramic
par Navigateur Ven 6 Juil 2018 - 12:59

Navigation
 Portail
 Index
 Membres
 Profil
 FAQ
 Rechercher
Rechercher
 
 

Résultats par :
 
Rechercher Recherche avancée
Juillet 2018
LunMarMerJeuVenSamDim
      1
2345678
9101112131415
16171819202122
23242526272829
3031     
CalendrierCalendrier

Partagez | 
 

 @ Klaus : DLL_OFF provoque un plantage ! [Résolu]

Aller en bas 
AuteurMessage
papydall

avatar

Nombre de messages : 5980
Age : 67
Localisation : Moknine (Tunisie) Entre la chaise et le clavier
Date d'inscription : 03/03/2012

MessageSujet: @ Klaus : DLL_OFF provoque un plantage ! [Résolu]   Dim 25 Fév 2018 - 0:24

@Klaus

dll_off ( après dll_on "kgf") provoque un plantage !






Le code suivant fonctionne parfaitement, mais si on enlève le REM de la dernière ligne, l’erreur est systématiquement au rendez-vous !


Code:

dim WB%,res%,url$
full_space 0
dll_on "kgf"
url$ = "http://papydall-panoramic.forumarabia.com/"
WB% = dll_call1("WB_Create",handle(0))
res% = dll_call5("WB_Locate",WB%,20,20,width_client(0)-50,height_client(0)-50)
res% = dll_call2("WB_Url",WB%,adr(url$))
' dll_off : ' <--- PANORAMIC_TEMP xxx.exe a cessé de fonctionner


dll_off ne provoque l'erreur qu’avec kgf.dll
Pour une autre dll, No Problem !
La preuve : le code suivant ne provoque pas d’erreur

Code:

dim ret% ,hwnd%
hwnd% = handle_canvas(0)
dll_on "gdi32"
ret% = dll_call5("Ellipse",hwnd%,50,50,150,200)
dll_off : ' <--- Pas d'erreur



Dernière édition par papydall le Dim 25 Fév 2018 - 2:30, édité 1 fois
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://papydall-panoramic.forumarabia.com/
Klaus

avatar

Nombre de messages : 11088
Age : 69
Localisation : Ile de France
Date d'inscription : 29/12/2009

MessageSujet: Re: @ Klaus : DLL_OFF provoque un plantage ! [Résolu]   Dim 25 Fév 2018 - 0:31

Normal, Papydall, enfin voyons !
Tu crées un Webrowser qui réside dans KGF.dll.
Tu l'attaches à la form 0.
Tu le fais naviguer vers une URL.
Puis tu veux supprimer la DLL ? Qu'est-ce ue tu fais du WebBrowser ? Si tu fermes la DLL, la référence au WebBrowser qui se trouve dans la form 0, pointe vers une adresse memoire qui a été libérée. et bouuuum ! Violation d'accès mémoire, que ce soit en lecture ou en écriture.

Faudra revoir ta copie...

EDIT

Un peu plus de "fond":
1. si tu crées un objet Panoramic, le fait de fermer le programme provoque toute une réaction en chaîne commandée par Windows: on parcourt la totalité des "enfants" de la fenêtre pour les supprimer, en cascade, et ainsi, ton objet Panoramic sera supprimé (et donc enlevé de la form 0) avant la suppression effective de la  form. Et donc, pas de pointeur invalide.
2. ton second code ne crée pas d'objet Windows et ne laisse dont rien en mémoire. Il écrit simplement, via une fonction DLL, dans un canvas qui est la propriété de la form 0 et n'a acun lien avec la DLL. Et donc, on peut décharger la DLL sans problème.

A la lumière de cela, tu vois déjà om est le problème. Le fait de décharger la DLL n'avertit pas la form 0 que l'objet WebBrowser n'existe plus. C'est comme si tu lui retirais une chaise sous le derrière - la chute est inévitable.

Seule solution: supprimer le WenBrowser avec la fonction approprirée avant de décharger la DLL.

Mais si tu as besoin de l'affichage de ce que le WebBrowser montre, il faut le laisser jusqu'au bout et le supprimer, par exemple dans l'évènement ON_CLOSE de la form 0. Ou alors, tu fais une capture d'écran, tu découpes l'image du WebBrowser et tu la charges dans un PICTURE...
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://klauspanoramic.comxa.com/index.html
papydall

avatar

Nombre de messages : 5980
Age : 67
Localisation : Moknine (Tunisie) Entre la chaise et le clavier
Date d'inscription : 03/03/2012

MessageSujet: Re: @ Klaus : DLL_OFF provoque un plantage ! [Résolu]   Dim 25 Fév 2018 - 1:13

DLL_OFF est innocente !

J’ai revu ma copie.
Si on tient à DLL_OFF, on doit d’abord supprimer le browser !

Code:

dim WB%,res%,url$
full_space 0
dll_on "kgf"
url$ = "http://papydall-panoramic.forumarabia.com/"
WB% = dll_call1("WB_Create",handle(0))
res% = dll_call5("WB_Locate",WB%,20,20,width_client(0)-50,height_client(0)-50)
res% = dll_call2("WB_Url",WB%,adr(url$))
message "ok"
res% = dll_call1("WB_Delete",WB%)
dll_off
font_bold 0 : font_size 0,24
 print_locate 100,100 : print "Fermeture dans 5 s ..."
 pause 5000
terminate


Et merci pour les explications : Tu es Le maître ! king
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://papydall-panoramic.forumarabia.com/
Klaus

avatar

Nombre de messages : 11088
Age : 69
Localisation : Ile de France
Date d'inscription : 29/12/2009

MessageSujet: Re: @ Klaus : DLL_OFF provoque un plantage ! [Résolu]   Dim 25 Fév 2018 - 1:56

De rien, Papydall ! Je me bats tous les jours avec ce genre de problèmes, et je commence à avoir l'habitude !

Tiens, je te présente un autre problème inextricable en apparence. Ca n'a rien à voir, quoique... encore une histoire de violation de mémoire à cause d'un pointeur devenu invalide:
Dans la Dll, je mémorise certaines chaînes de caractères en provenance de Panoramic. Noms de fichiers, textes simples, codes, .. enfin, de simples chaînes de caractères. Sauf qu'en Delphi, une chaîne de caractères est tout sauf simple ! En fait, c'est une zone de mémoire dynamique allouée par le Memory Manager intégré dans Delphi (et donc utilisé par Panoramic !) et qui garde évidemment la trace de chaque petite parcelle de mémoire alouée. Et Delphi optimise assez fortement ses traitements. C'est pourquoi une chaîne de caractères est assimilée à un pointeur, associé à un compteur de révérence. Ce compteur indique combien d'instances différentes font référence à la chaîne de caractères en question. Et tant qu'on l'utilise uniquement en lecture, pas de problème. Mais si une partie du programme modifie la chaîne, le Memory Manager crée immédiatement une copie de la chaîne initiale, donne la copie au module qui veut modifier en mémorisant un compteur de référence de 1 pour cette nouvelle chaîne, puis décrémente le compteur de référence de la chaîne d'origine. Et ce n'est que lorsque ce compteur de référence tombe à zéro que la mémoire allouée à cette chaîne est libérée.

Ouf ! C'est dit. C'est clair jusque là ? Alors, on continue, si tu veux bien.

Panoramic ne sait pas vraiment passer une chaîne de caractères en paramètre à une fonction DLL? C'est dommage, mais c'est comme ça. Et donc, on passe adr(s$). On en a tellement l'habitude qu'on ne se rend même plus compte de ce que ça veut dire. Reprenons: adr$(s$) donne l'adresse, non pas du premier caractère de la chaîne (pourquoi faire simple quand on peut faire compliqué !), mais donne l'adresse d'un mot de 32 bits qui, lui, contient l'adresse du premier caractère de la chaîne ! A partir de cette adresse indirecte, on a tous les octets de la chaîne, et un octet supplémentaire: un octet zéro binaire marquant la fin de la chaîne. C'est ce que d'autres langages appellent le format ASCIZ. Mais ce n'est pas tout ! Les deux mots de 32 bits qui précèdent le premier octet de la chaîne contiennent la longueur de la chaîne sur 32 bits, ainsi que le fameux compteur de référence ! On a donc le format suivant:
adr(s$) ==> adresse A
32 bits compteur de référence <=== offset -8 sur l'adresse A
32 bits longueur de la chaîne N <=== offset -4 sur l'adresse A
N caractères <=== ici, adresse A !
1 octet zéro binaire
Maintenant, je prends cette chaîne dans ma DLL. Panoramic (et donc le Memory Manager de Delphi étant linké aec Panoramic) n'en sait rien du tout ! Par contre, le Memory Manager linké avec la DLL, lui, en a connaissance et gère donc ""son" compteur de référence. Et tant que j'utilise cette chaîne sans la modifier, et tant que je ne supprime pas l'objet (un équivalent de DLIST en Delphi, par exemple), tout se passe bien. Ce sont simplement des pointeurs qui sont copiés, et comme la mémoire ne change pas, les pointeurs restent valides. Tu commences à sentir d'où vient le vent ?
Maintenant, je supprime un des objets (genre DLIST interne, ou un des objets créés dans KGF.dll comme un RichEdit etc), c'est immédiatement la pagaille entre les pointeurs et les compteurs de référence. Il y a forcément, à un moment ou un autre, un des deux Memory Managers qu veut accéder à la mémoire occupée par la chaîne, et c'est le crash. Cela peut se produire beaucoup plus tard que le fait déclencheur, par exemple simplement à l'arrêt du programme.
J'ai vraiment galéré longtemps pour trouver la solution. J'ai même demandé de l'aide à des forms spécialisés, et j'ai reçu une solution, complexe mais qui marche. Seulement, c'est un boulot énorme de mettre cela en oeuvre partout dans KGF.dll où ce serait nécessaire.
Mais j'ai fini par trouver un moyen simple de "tromper" les deux Memory Managers qui se croient les maîtres du jeu. Je fais maintenant dans la DLL, en Delphi, systématiquement ce qu'en Panoramic, on coderait comme suit:
Code:
MaChaineInterne$ = trim$(ChaineTransmiseDePanoramic$+" ")
Ca paraît dingue, mais ça marche. L'optimisation du code par le compilateur Delphi n'y voit que du feu, et l'effet net est que mon expression créer une chaîne de caractères interne, temporaire, incrémentant le compteur de référence de la chaîne d'origine puisqu'il y a une référence, et cette chaîne de caractères interne aura le compteur de référence 1 attribué par l'affectation dans la variable MaChaineInterne$. Jusque là, tout va bien.
Maintenant, je termine ma fonction DLL qui a fini son boulot. Qu'est-ce qui se passe ? MaChaineInterne$ est, soit une variable globale dont la durée de vie est la durée de chargement de la DLL, soit un stockage interne dans un objet Delphi comme un RichEdit, par exemple. Donc, permanent aussi, tant que l'objet n'est pas supprimé. Tu commences à voir le lien avec ton problème ? Maintenant, je sors de ma fonction (équivalent de RETURN). Qu'est-ce qui se passe ? L'objet Delphi ou la variable globale persistent. Bien. Mais ma chaîne temporaire (le résultat de l'expression, avant affectation dans ma variable) sera libérée par le Memory Manager de la DLL. Et automatiquement, juste avant, cette chaîne temporaire sera cette fois copiée dans la fameuse variable ou dans l'objet Delphi, et le fait de supprimer ensuite cette variable temporaire décrémente également le compteur de référence de la chaîne passée en paramètre.
Et Voilà. Le tour est joué: avec uen simple expression "idiote", les deux Memory Managers n'ont pas vu que je garde en réalité une copie de la chaîne d'origine qui a échappé à leur contrôle. Et il n'y a plus de violation de mémoire !

Bon, j'espère que je ne t'ai pas trop saoûlé avec mes élucubrations techniques. Tout ça pour montrer que c'est un problème oh combien fréquent qui me hante tous les jours? Je te fais grâce des multiples variantes mais qui conduisent toutes au même résultat: libérer une partie de mémoire qui est encore référencée ailleurs.
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://klauspanoramic.comxa.com/index.html
papydall

avatar

Nombre de messages : 5980
Age : 67
Localisation : Moknine (Tunisie) Entre la chaise et le clavier
Date d'inscription : 03/03/2012

MessageSujet: Re: @ Klaus : DLL_OFF provoque un plantage ! [Résolu]   Dim 25 Fév 2018 - 2:33

Klaus, même si je ne comprends pas toujours ce que tu écris, j’aime bien te lire.
Tu sais comment expliquer d’une manière simple les choses complexes.
Merci, merci pour tout ce que tu fais.
Celui qui donne des explications aux autres, finit bien par consolider ses connaissances.
Alors, tu as intérêt à continuer d’être « le maitre  qui-sait-presque-tout-et-qui-n’ignore-presque-rien » king


J'ai modifié le titre de mon post en y ajoutant [Résolu]
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://papydall-panoramic.forumarabia.com/
silverman

avatar

Nombre de messages : 659
Age : 46
Localisation : Picardie
Date d'inscription : 18/03/2015

MessageSujet: Re: @ Klaus : DLL_OFF provoque un plantage ! [Résolu]   Dim 25 Fév 2018 - 10:36

Klaus, cette explication technique est vraiment très interessante! On n'imagine pas tout ce qui se passe derrière une simple affectation de chaine.
Si j'ai bien compris, créer 'MaChaineInterne$' revient à faire comprendre au memorymanager de la dll que 'ChaineTransmiseDePanoramic$' existe! Il travaille ensuite sur une instance de 'ChaineTransmiseDePanoramic$' qui est 'MaChaineInterne$' c'est bien ça?
Dans mes dlls, je cré systématiquement une copie de 'ChaineTransmiseDePanoramic$' et je travaille sur la copie, et ensuite je met à jour la chaine originale (copy memory). Sans le savoir, je faisait bien! Very Happy
Que se passerait-il si tu trompais le memorymanager linké à panoramic en incrémentant manuellement de 1 le compteur de référence de 'ChaineTransmiseDePanoramic$'? Tu devrait pouvoir te passer de 'MaChaineInterne$' ensuite, non?
Revenir en haut Aller en bas
Voir le profil de l'utilisateur
Klaus

avatar

Nombre de messages : 11088
Age : 69
Localisation : Ile de France
Date d'inscription : 29/12/2009

MessageSujet: Re: @ Klaus : DLL_OFF provoque un plantage ! [Résolu]   Dim 25 Fév 2018 - 11:34

Citation :
Que se passerait-il si tu trompais le memorymanager linké à panoramic en incrémentant manuellement de 1 le compteur de référence de 'ChaineTransmiseDePanoramic$'? Tu devrait pouvoir te passer de 'MaChaineInterne$' ensuite, non?
Oui et non. J'ai essayé. Effectivement, cela permet de tromper le Memory Manager de Panoramic. Pas celui de la DLL, malheureusement. Normalement, je faisais comme ceci:
Code:
Panoramic:
dim s$
s$ = "Ma chaîne Panoramic"
res% = dll_call1("test",adr(s$))

DLL en Delphi:
function test(s: pstring):integer; stdcall; export;
begin
  MyExternalRichEdit.Lines.Add(s^);
  result := 0;
end;
exports test;
Cela provoque une violation de mémoire, soit en sortant de la fonction, soit en arrêtant le programme Panoramic, selon les circonstances. Normal: la méthode Add transfère un pointeur vers une variable temporaire (construite par l'opération de déréferencement s^), et en sortant de la fonction, cette variable temporaire n'existe plus. Tant qu'on n'essaie pas d'accéder à cet élément du RichEdit, tout va bien. Mais dès qu'un accès est fait (affichage,, lecture de la ligne, suppression du RichEdit, ...) le pointeur est invalide.

Je fais maintenant comme ceci:
Code:
Panoramic:
dim s$
s$ = "Ma chaîne Panoramic"
res% = dll_call1("test",adr(s$))

DLL en Delphi:
function test(s: pstring):integer; stdcall; export;
var
  temp: string
begin
  temp := trim(s^+' ');
  MyExternalRichEdit.Lines.Add(temp);
  result := 0;
end;
exports test;
et je n'ai plus de problème. En fait, cela revient à faire ce que tu fais: copier la chaîne d'abord par une méthode quelconque de copie d'octet par octet, via des poiteurs (surtout pas par une affectation de variable !), puis travailler sur la copie.
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://klauspanoramic.comxa.com/index.html
Contenu sponsorisé




MessageSujet: Re: @ Klaus : DLL_OFF provoque un plantage ! [Résolu]   

Revenir en haut Aller en bas
 
@ Klaus : DLL_OFF provoque un plantage ! [Résolu]
Revenir en haut 
Page 1 sur 1
 Sujets similaires
-
» Remise à jour cartographie sur Nuvi 250 : gros plantage [résolu]
» [résolu]plantage de mon navigateur sous seven
» [résolu]pc infecté par wwwzuc32.exe
» [ résolu ]à propos de TFC
» Optimisation sécurité PC [Résolu]

Permission de ce forum:Vous ne pouvez pas répondre aux sujets dans ce forum
FORUM DE DISCUSSION SUR LE LANGAGE PANORAMIC :: PANORAMIC :: Présentation et bavardage-
Sauter vers: