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
» Mah-Jong européen new-look
par jjn4 Aujourd'hui à 15:48

» KGF.dll - demandes ou suggestions de modifications ou ajouts
par pascal10000 Aujourd'hui à 13:46

» a l'aide klaus
par Minibug Aujourd'hui à 11:42

» KGF_dll - nouvelles versions
par Minibug Aujourd'hui à 1:48

» bug SYNEDIT_TARGET_IS_OBJECT
par Jack Aujourd'hui à 0:16

» Jukebox : Serge Reggiani
par papydall Sam 9 Déc 2017 - 5:58

» Ecouter la radio fm sur votre pc
par pascal10000 Sam 9 Déc 2017 - 3:42

» anomalie
par Klaus Sam 9 Déc 2017 - 3:21

» hommage
par Jicehel Ven 8 Déc 2017 - 11:29

» Logiciel de soutien scolaire en langues.
par Pedro Alvarez Ven 8 Déc 2017 - 10:43

» carte son
par Klaus Ven 8 Déc 2017 - 2:37

» API Windows
par Klaus Jeu 7 Déc 2017 - 21:03

» mise a jour calculatrice
par joeeee2017 Mer 6 Déc 2017 - 22:19

» j'ai un petit problème
par JL35 Mer 6 Déc 2017 - 21:58

» source vumetre avec delphi
par Klaus Mar 5 Déc 2017 - 23:22

Navigation
 Portail
 Index
 Membres
 Profil
 FAQ
 Rechercher
Rechercher
 
 

Résultats par :
 
Rechercher Recherche avancée
Décembre 2017
LunMarMerJeuVenSamDim
    123
45678910
11121314151617
18192021222324
25262728293031
CalendrierCalendrier

Partagez | 
 

 Aide avec codage de DLL en Delphi

Voir le sujet précédent Voir le sujet suivant Aller en bas 
AuteurMessage
Klaus

avatar

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

MessageSujet: Aide avec codage de DLL en Delphi   Mer 18 Mar 2015 - 3:39

@Jack
Je pense que la question qui suit, s'adressera uniquement à Jack, bien que le sujet soit ouvert à tous.

Depuis des années, je code KGF.dll, en Delphi 6 Personal Edition. J'ai bien intégré les contraintes liées à l'interfaçage avec Panoramic, c'est du moins ce que je pense. Et pourtant, je rencontre de sporadiques violations de mémoire, en cours d'exécution, et souvent en sortie du programme qui ne veut pas se terminer proprement.

ET depuis deux jours, j'arrive enfin à le reproduire systématiquement, avec un code très réduit. J'hésite à placer ce post dans la rubrique des bugs, car j'ai tendance à toujours chercher le problème entre mes mains et mon écran, mais j'ai un doute....

Voilà la situation. J'ai fait une minuscule DLL nommée KGF_GRID.dll qui contient une seule fonction: SetGridSeparators, qui a deux paramètres. Voici le fichier KGF_GRID.dpr:
Code:
library KGF_GRID;


uses
  Classes, Controls, StrUtils, Grids, Types, Graphics, Dialogs, Windows;

var
  SG_line_separator, SG_cell_separator: string;
  SG_ColorCol, SG_ColorRow:  integer;
  SG_color: TColor;

{$R *.res}

function SetGridSeparators(sepcel, seplin: pstring):integer; stdcall; export;
begin
  SG_line_separator := seplin^;
  SG_cell_separator := sepcel^;
showmessage('['+SG_cell_separator+'] ['+SG_line_separator+']');
  result := 0;
end;


exports
  SetGridSeparators  ;

begin
end.

Et voici le code Panoramic qui va avec:
Code:
' demo_GetSelectedGridText.bas
label clic
dim res%, sepcel$, seplin$

grid 1 : top 1,100 : left 1,10
grid_write 1,2,2,"aaa"
grid_write 1,2,3,"bbb"
grid_write 1,3,3,"ccc"
on_click 1,clic

dll_on "KGF_GRID.dll"
end

exit:
  res% = dll_call1("KillProcessByHandle",handle(0))
  message str$(res%)
  return

clic:

  ' paramétrer les séparateurs (ce sont d'ailleurs les valeurs par défaut)
  sepcel$ = ""
  seplin$ = chr$(13)+chr$(10)
  ' >>>>>>>>> la ligne suivante provoque le problème: <<<<<<<<<<<<<
  res% = dll_call2("SetGridSeparators",adr(sepcel$),adr(seplin$))
  message str$(res%)
return

Il faut sélectionner un rectangle de cellules avec la souris, ou simplement cliquer dans le GRID. Il y aura deux messages: un venant de la DLL, l'autre du programme Panoramic (juste pour contrôler). Après quelques tentatives (2, 3 ouun peu plus), il y a ceci:
" />
suivi de:
" />
Souvent, il faut tuer le process par le gestionnaire des tâches.

Alors, j'ai fait un programme Delphi créant un TStringGrid, chargeant la DLL dynamiquement et appelant la même fonction. Et là, pas de problème ! La fonction s'exécute normalement, autant de fois qu'on veut, et en sortie, pas de crash, pas besoin d'utiliser la TaskManager pour arrêter le programme. Voici le fichier Test_KGF_GRID.dpr:
Code:
program Test_KGF_GRID;

uses
  Forms,
  Test_KGF_GRID_Unit1 in 'Test_KGF_GRID_Unit1.pas' {Form1};

{$R *.res}

begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.
Voici Test_KGF_GRID_unit1.dfm:
Code:
object Form1: TForm1
  Left = 198
  Top = 117
  Width = 928
  Height = 480
  Caption = 'Text_KGF_GRID'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object StringGrid1: TStringGrid
    Left = 120
    Top = 80
    Width = 320
    Height = 120
    TabOrder = 0
    OnClick = StringGrid1Click
  end
end
et Test_KGF_GRID_unit1.pas:
Code:
unit Test_KGF_GRID_Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Grids;

type
  TForm1 = class(TForm)
    StringGrid1: TStringGrid;
    procedure FormCreate(Sender: TObject);
    procedure StringGrid1Click(Sender: TObject);
  private
    { Déclarations privées }
  public
    { Déclarations publiques }
  end;

type
  TSetGridSeparators = function(sepcel, seplin: pstring):integer; stdcall;

var
  Form1: TForm1;
   dllHandle : cardinal;
   SetGridSeparators : TSetGridSeparators;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  StringGrid1.Cells[2,2] := 'aaa';
  StringGrid1.Cells[2,3] := 'bbb';
  StringGrid1.Cells[3,3] := 'ccc';

//  dllHandle := LoadLibrary('KGF.dll');
  dllHandle := LoadLibrary('KGF_GRID.dll');
  
  if dllHandle <> 0 then begin
    @SetGridSeparators := GetProcAddress(dllHandle, 'SetGridSeparators') ;
    if not Assigned (SetGridSeparators) then begin
      ShowMessage('"SetGridSeparators" function not found') ;
      FreeLibrary(dllHandle) ;
      application.Terminate;
    end;
  end else begin
    ShowMessage('KGF_GRID.dll not found / not loaded') ;
    application.Terminate;
  end;
end;

procedure TForm1.StringGrid1Click(Sender: TObject);
var
  seplin,sepcel: string;
  res: integer;
begin
      seplin := #13#10;
      sepcel := '\';
      res := SetGridSeparators(@sepcel,@seplin) ; //call the function
      showmessage(inttostr(res));
end;

end.
ainsi que Test_KGF_GRID.dof (généré automatiquement, juste pour info):
Code:
[FileVersion]
Version=6.0
[Compiler]
A=8
B=0
C=1
D=1
E=0
F=0
G=1
H=1
I=1
J=0
K=0
L=1
M=0
N=1
O=1
P=1
Q=0
R=0
S=0
T=0
U=0
V=1
W=0
X=1
Y=1
Z=1
ShowHints=1
ShowWarnings=1
UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
[Linker]
MapFile=0
OutputObjs=0
ConsoleApp=1
DebugInfo=0
RemoteSymbols=0
MinStackSize=16384
MaxStackSize=1048576
ImageBase=4194304
ExeDescription=
[Directories]
OutputDir=
UnitOutputDir=
PackageDLLOutputDir=
PackageDCPOutputDir=
SearchPath=
Packages=
Conditionals=
DebugSourceDirs=
UsePackages=0
[Parameters]
RunParams=
HostApplication=
Launcher=
UseLauncher=0
DebugCWD=
[Version Info]
IncludeVerInfo=0
AutoIncBuild=0
MajorVer=1
MinorVer=0
Release=0
Build=0
Debug=0
PreRelease=0
Special=0
Private=0
DLL=0
Locale=1036
CodePage=1252
[Version Info Keys]
CompanyName=
FileDescription=
FileVersion=1.0.0.0
InternalName=
LegalCopyright=
LegalTrademarks=
OriginalFilename=
ProductName=
ProductVersion=1.0.0.0
Comments=
et Test_KGF_GRID.cfg (généré, juste pour info):
Code:
-$A8
-$B-
-$C+
-$D+
-$E-
-$F-
-$G+
-$H+
-$I+
-$J-
-$K-
-$L+
-$M-
-$N+
-$O+
-$P+
-$Q-
-$R-
-$S-
-$T-
-$U-
-$V+
-$W-
-$X+
-$YD
-$Z1
-cg
-AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
-H+
-W+
-M
-$M16384,1048576
-K$00400000
-LE"c:\program files (x86)\borland\delphi6\Projects\Bpl"
-LN"c:\program files (x86)\borland\delphi6\Projects\Bpl"

Alors, ma question est:
Pourquoi ça marche avec Delphi/Delphi, mais pas avec Panoramic/Delphi ?
Qu'est-ce que j'ai raté au niveau de l'utilisation de l'interface Panoramic vers DLL ?
Ou y aurait-il un problème dans Panoramic au niveau du chargement dynamique d'une DLL ?

Ca fait des mois que je me bats avec ce problème sporadique, et depuis 2 jours, c'est devenu systématique. Et j'ai réussi à le reproduire avec ce code réduit au minimum. Je ne vois pas comment aller plus loin tout seul. Pourrais-tu m'aider, Jack ?
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://klauspanoramic.comxa.com/index.html
Jicehel

avatar

Nombre de messages : 5863
Age : 45
Localisation : 77500
Date d'inscription : 19/04/2011

MessageSujet: Re: Aide avec codage de DLL en Delphi   Mer 18 Mar 2015 - 10:09

Puisque ça aide à faire des dll (peut être même qu'un jour je me lancerais dans l'aventure aussi Wink )pour ajouter les compléments à Panoramic dont nous avons besoin pour faire ce que nous avons en tête, c'est forcément utile. J'espère que vous trouverez la solution.
Revenir en haut Aller en bas
Voir le profil de l'utilisateur
Klaus

avatar

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

MessageSujet: Re: Aide avec codage de DLL en Delphi   Jeu 19 Mar 2015 - 20:45

Jack, si tu avais l'occasion de regarder ce petit code, ça m'arrangerait. Je suis bloqué à ce niveau. Je sais que tu es loin et que tu ne disposes pas de tout ce qu'il faut, là où tu es. Mais donne-moi stp une petite info pour confirmer que tu as bien vu ce problème.

J'attends la solution de cet aspect pour donner accès aux fonctions de gestion des GRID par DLL. En-dehors de ce que j'ai déjà publié (retourner les indices du rectangle de cellules sélectionné, retourner une chaîne de caractères contenant toutes les cellules sélectionnées et remplacer d'un coup toutes les cellules d'un rectangle de cellules), j'ai fait des fonctions qui marchent bien: activer/désactiver le mode édition pour pouvoir saisir directement dans un GRID, et choisir la couleur de fond d'une ligne, d'une colonne et/ou d'une cellule, pour autant d'éléments qu'on veut. Je pense que ça peut être utile.
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://klauspanoramic.comxa.com/index.html
Jack
Admin
avatar

Nombre de messages : 1771
Date d'inscription : 28/05/2007

MessageSujet: Re: Aide avec codage de DLL en Delphi   Ven 20 Mar 2015 - 12:35

Je n'ai pas tout mon "attirail" pour regarder en détail ce qui se passe, mais dès que je le peux, je décortiquerai ton code.
En fait, je te répond maintenant, même si ma réponse n'est pas complète, pour que tu ne t'imagine pas que je délaisse ton problème.

A la lecture des différents codes que tu proposes, une chose me chagrine.

Dans KGF_GRID.dpr, tu fais:
Code:
SG_line_separator := seplin^;
SG_cell_separator := sepcel^;
alors que SG_line_separator et SG_cell_separator sont du type String Delphi, et que seplin et sepcel sont des PString Delphi.

Je suis d'accord avec le fait que seplin et sepcel sont des pointeurs sur des strings, mais je ne vois pas comment, on peut récupérer de cette façon correctement un string qui n'est pas codé en "zero-terminal", c'est à dire qui n'est pas terminé par un 0.

Dans l'appel en Panoramic :
res% = dll_call2("SetGridSeparators",adr(sepcel$),adr(seplin$))
adr(string) donne certes, l'adresse d'un string, mais pas d'un string "zero-terminal".
en Panoramic, faire adr(string) revient à faire integer(addr(string)) en Delphi, ce qui est différent de ton deuxième exemple où "ça marche".
integer(addr(string)) est sans doute différent de @string.

J'ai compilé ton exemple Test_KGF_GRID.dpr pour obtenir Test_KGF_GRID.dll et quand j'exécute demo_GetSelectedGridText.bas, j'obtiens :
- à l'exécution un message correct affichant sepcel$ et seplin$
- à la fermeture, un message d'erreur :
The instruction at "0x013934ce" referenced memory at "0x01437e8". The memory could not be "read".
Click OK to terminate the program

Puis : Runtime error 216 at 013934CE, c'est à dire sur l'instruction qui veut lire en mémoire en dehors du domaine de l'application.

En conclusion (provisoire), je pense que le problème vient du fait que ces 3 instructions ne sont pas cohérentes (je n'ose pas dire compatibles) :
integer(addr(string))
@string
string := pstring^

_________________
username : panoramic@jack-panoramic password : panoramic123
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://panoramic.free-boards.net
Klaus

avatar

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

MessageSujet: Re: Aide avec codage de DLL en Delphi   Ven 20 Mar 2015 - 13:40

Merci beaucoup d'avoir regardé mon problème, Jack.

Tu dis:
Citation :
Je suis d'accord avec le fait que seplin et sepcel sont des pointeurs sur des strings, mais je ne vois pas comment, on peut récupérer de cette façon correctement un string qui n'est pas codé en "zero-terminal", c'est à dire qui n'est pas terminé par un 0.
Mais en réalité, il y a toujours un byte ZERO après le texte des strings qui sont passés par adr(s$). JE ne sais évidemment pas comment c'est réalisé en interne, par Panoramic, mais vu par la DLL, je constate que ce sont toujours des strings ASCIZ. Au début, je faisais une gymnastique complexe à l'aide d'un pointeur, pour récupérer les données. Mais un traçage avec affichage de la valeur des bytes récupérés le montre parfaitement.

Dailleurs, comme Panoramic ne passe que l'adresse, comment saurais-je la fin du string s'il n'y avait pas de ZERO derrière ? Heureusement que ça marche comme ça ! Et j'utilise cette technique depuis des années, dans des dizaines de fonctions. Quelques exemples: toutes les fonctions utilisant un nom de fichier, un libellé, une URL, ...

Mais, cette discussion m'a fait réfléchir à l'usage d'un PSTRING. En effet, par la ligne
Code:
SG_line_separator := seplin^;
Delphi copie simplement l'adresse et non les données elles-mêmes. Et lorsque les données changent, le pointer copié devient invalide, d'où le crash. Il suffit de faire
Code:
SG_line_separator := trim(seplin^);
par exemple, pour que les données elles-mêmes sont copiées, et comme par miracle, tout fonctionne.

Je te suis très reconnaissant d'avoir étudié mon code. J'étais mentalement totalement bloqué sur ce probème, et tu m'as donné l'indication indispensable pour dépasser cela, en suscitant une réflexion sur le sens de PSTRING.

Je produirai dans la journée une version corrigée de KGF.dll qui n'aura plus de problème. Et, progressivement, je vais sécuriser toutes les fonctions de KGF.dll, de cette manière, si elles utilisent PSTRING en paramètre.
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://klauspanoramic.comxa.com/index.html
papydall

avatar

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

MessageSujet: Re: Aide avec codage de DLL en Delphi   Ven 20 Mar 2015 - 14:30

Quand un Klaus rencontre un Jack, ça donne des KJ (Kilojoules)
Comme le J (joule) est une unité qui quantifie l’énergie, le travail, on profite de ces kilos d’énergie et de travail.
Merci Klaus.
Merci Jack.

Spoiler:
 
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://papydall-panoramic.forumarabia.com/
Yannick

avatar

Nombre de messages : 8002
Age : 46
Localisation : Bretagne
Date d'inscription : 15/02/2010

MessageSujet: re   Ven 20 Mar 2015 - 23:38

cheers  Génial !
Revenir en haut Aller en bas
Voir le profil de l'utilisateur
Contenu sponsorisé




MessageSujet: Re: Aide avec codage de DLL en Delphi   

Revenir en haut Aller en bas
 
Aide avec codage de DLL en Delphi
Voir le sujet précédent Voir le sujet suivant Revenir en haut 
Page 1 sur 1
 Sujets similaires
-
» Besoin d'un peu d'aide avec ma nouvelle config!
» besoin aide avec sonar
» Des loup a l'aide! (avec AppleJack et moi^^)
» Aide avec opacité réduite...
» gros problème avec mon ordinateur, besoin d'aide

Permission de ce forum:Vous ne pouvez pas répondre aux sujets dans ce forum
FORUM DE DISCUSSION SUR LE LANGAGE PANORAMIC :: PANORAMIC :: A l'aide!-
Sauter vers: