IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Delphi Discussion :

Serait-ce un bug Delphi ?


Sujet :

Langage Delphi

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    803
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 803
    Points : 182
    Points
    182
    Par défaut Serait-ce un bug Delphi ?
    Bonjour,

    J'ai posté un message hier à propos d'une violation d'accès inexpliquée. 17 lectures et aucune réponse. Il est vrai qu'au moment de la rédaction de ce message je venais tout juste de faire le constat. Depuis hier j'ai mieux cerné le problème.

    En fait dans une procédure graphique il s'agit de dessiner sur un ACanvas : TCanvas passé en paramètre dans une procédure.
    La procédure modifie des couleurs et fait donc appel à la méthode ACanvas.Brush.Color := CouleurMachin;

    Si cette procédure se trouve dans le code de l'exécutable aucun problème.
    Si la même procédure est transférée dans une DLL elle fonctionne également sans problème mais à la fermeture de l'exécutable elle déclanche une erreur violation d'accès !

    Tout se passe comme si la DLL n'accepte pas la méthode TCanvas.Brush.Color = UneCouleur, alors que cette méthode utilisée strictement de même façon dans un exécutable ne pose aucun problème.

    Pour info
    1) dans la DLL la méthode TCanvas.Pen.Color ne pose elle aucun problème.
    2) J'utilise D 2007

    Qui a une explication ?
    Et surtout Qui sait comment corriger ce genre de Bug, car j'ai besoin que ladite procédure soit dans une DLL

    Merci pour votre aide à tous

  2. #2
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    Euh ben l'explication c'est que DLL + objets = Boom !
    On ne peut pas transférer d'objet d'une app à une DLL ou vice versa : tu cours directement à la catastrophe.

    Pour "solutionner" ton problème, tu peux soit utiliser ShareMem (ce qui devrait permettre de transmettre des objets) soit utiliser des paquets runtime à la place de DLL.

  3. #3
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 457
    Points
    28 457
    Par défaut
    Citation Envoyé par sjrd Voir le message
    Euh ben l'explication c'est que DLL + objets = Boom !
    On ne peut pas transférer d'objet d'une app à une DLL ou vice versa : tu cours directement à la catastrophe.

    Pour "solutionner" ton problème, tu peux soit utiliser ShareMem (ce qui devrait permettre de transmettre des objets) soit utiliser des paquets runtime à la place de DLL.
    ShareMem permet de partager le même gestionnaire de mémoire entre l'EXE et la DLL...mais ça ne permet pas pour autant de partager les objets.

    C'est techniquement possible de le faire mais je ne le recommande absolument pas.

    Exemple, tu crées un objet X que tu manipules dans ton EXE et dans ta DLL. L'exe et la dll possèdent chacun une version (identique pour l'instant) de la structure de l'objet et de son code.

    Si l'exe crée un l'objet et que la DLL invoque une de ses méthodes, deux solutions:
    1) la méthode est statique, c'est un appel direct au code de la DLL appliqué à l'instance de l'exe
    2) la méthode est dynamique (virtuelle) c'est le code de l'EXE qui est invoqué via son adresse dans l'instance objet.

    Maintenant je modifie l'objet et recompile l'exe...si je ne recompile pas la DLL j'ai une différence entre les deux codes et probablement des erreurs d'adresse de méthodes ou de propriétés.

    Idem si je recompile les deux mais avec des versions différentes de Delphi dans lesquels l'objet ancêtre a été modifié !

    Bref, c'est une situation qui est à mon sens particulièrement risquée.

    Deux solutions :

    1) passer par une API à plat, l'objet peut être transmis mais il est déclaré sous un type opaque THandle et non comme objet

    côté DLL, on manipule un objet
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    function GetHandle: TMonObjet;
    begin
     Result := TMonObjet.create;
    end;
     
    procedure SetBrushColor(Obj: TMonObjet; Color: Integer);
    begin
      Obj.Canvas.Color := Color;
    end;
    côté EXE, on manipule un Handle sans savoir que c'est un objet
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    function GetHandle: THandle; external 'madll.dll';
    procedure SetBrushColor(Obj: THandle; Color: Integer); external 'madll.dll';

    2) utiliser un Interface, ça présente l'avantage de garder la notion objet et on peut librement modifier l'objet tant qu'il implémente toujours l'interface initiale. Au besoin on créera une nouvelle interface et l'objet supportera les deux afin de garder la compatibilité avec les anciennes DLL

  4. #4
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    Exemple, tu crées un objet X que tu manipules dans ton EXE et dans ta DLL. L'exe et la dll possèdent chacun une version (identique pour l'instant) de la structure de l'objet et de son code.
    Ah oui c'est vrai, c'était le véritable problème.
    J'ai presque honte de ne pas m'en être souvenu

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    803
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 803
    Points : 182
    Points
    182
    Par défaut Très intéressant
    Bonjour srdj,

    Est-ce qu'avec un TForm celà marche aussi ? du type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    function DLL_GetFormHandle: TForm;
    begin
     Result := TForm.create(nil);
     Result.pixelformat:= pf24bit;
     Result.modalResult:= mrOk;
    end;
    et du côté exécutable :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    var
      FormTruc: TObject;
    Begin
      FormTruc:= DLL_GetFormHandle;
      try
        FormTruc.showmodal;
      finally
        FormTruc.Free;
      end;
    Et si celà marche comment passer les paramètres à la TForm, dans l'exécutavble ou dans la DLL ?

  6. #6
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 457
    Points
    28 457
    Par défaut
    Citation Envoyé par colorid Voir le message
    Bonjour srdj,

    Est-ce qu'avec un TForm celà marche aussi ? du type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    function DLL_GetFormHandle: TForm;
    begin
     Result := TForm.create(nil);
     Result.pixelformat:= pf24bit;
     Result.modalResult:= mrOk;
    end;
    et du côté exécutable :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    var
      FormTruc: TObject;
    Begin
      FormTruc:= DLL_GetFormHandle;
      try
        FormTruc.showmodal;
      finally
        FormTruc.Free;
      end;
    Et si celà marche comment passer les paramètres à la TForm, dans l'exécutavble ou dans la DLL ?
    non !

    solution 1:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
     
    function DLL_GetFormHandle: THandle; external 'madll.dll';
    function DLL_ShowModal(Form: THandle); external 'madll.dll';
    function DLL_FreeForm(Form: THandle); external 'madll.dll';
     
    var 
      Form: THandle;
    begin
      Form := DLL_GetFormHandle;
      try
        DLL_ShowModal(Form);
      finally
        DLL_FreeForm(Form);
      end;
    end;
     
    // côté DLL
    function DLL_GetFormHandle: TForm;
    begin
      Result:= TForm.CreateNew();
    end;
     
    function DLL_ShowModal(Form: TForm);
    begin
      Form.ShowModal;
    end;
     
    function DLL_FreeForm(Form: TForm);
    begin
      Form.Free;
    end;
    solution 2:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    type
      IForm = Interface
       procedure ShowModal;
      end;
     
      TMyForm = class(TForm, IForm)
      end;
     
    function DLL_GetForm: IForm;
    begin
      Result:= TMyForm.Create(nil);
    end;
     
    // côté EXE
     
    var
      Form: IForm;
    begin
      Form := DLL_GetForm; 
      Form.ShowModal;
    end;

Discussions similaires

  1. Bug Delphi 2005
    Par fernet dans le forum EDI
    Réponses: 2
    Dernier message: 25/10/2010, 14h02
  2. Comment signaler un bug Delphi ?
    Par emile rabin dans le forum EDI
    Réponses: 4
    Dernier message: 03/05/2009, 12h00
  3. Bug Delphi 2006 Application.Helpjump('xxxxx')
    Par gaby277 dans le forum Débuter
    Réponses: 1
    Dernier message: 21/03/2008, 10h29
  4. [delphi 5 Pro] bug ?
    Par mariustrezor dans le forum Bases de données
    Réponses: 6
    Dernier message: 12/10/2004, 13h44
  5. [Delphi 7][Win 2000][IconeTray]Bug ?
    Par Giovanny Temgoua dans le forum Langage
    Réponses: 2
    Dernier message: 02/09/2004, 18h09

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo