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 :

[Package] Violation d'accès


Sujet :

Langage Delphi

  1. #1
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 235
    Points : 8 504
    Points
    8 504
    Par défaut [Package] Violation d'accès
    Mon logiciel fait appel à des packages dynamiquement en utilisant les interfaces.

    Code Delphi : 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
    33
    34
    35
    36
    37
     
    procedure TfrmMain.LoadPackages(iNum: integer; sName: String);
    type
      TMenuPluginFunc = function : TMenuPlugin;stdcall;
      TCreatePluginFunc = function : IPlugin; stdcall;
    var
      PackageHandle,Flags : integer;
      MenuPlugin : TMenuPluginFunc;
      CreatePlugin : TCreatePluginFunc;
    //  lst : TStringList;
    //  i : integer;
    begin
       SetLength(Plugin, iNum + 1);
       try
        Memo1.Lines.Add('Chargement du Package : ' + sName);
        PackageHandle := LoadPackage(sName);
       Except on E:Exception do
         begin
           memo1.Lines.Add('Load error : ' + E.Message);
           Exit;
         end;
       end;
       Memo1.Lines.Add('Information du Package :');
       GetPackageInfo(PackageHandle,nil,Flags,ShowInfoProc);
        // récupération des informations pour la création d'un bouton dans la barre
       MenuPlugIn := GetProcAddress(PackageHandle,'GetVersionMenu');
       Memo1.Lines.SaveToFile(GAPPPATH + 'LoadLog.txt');
       Plugin[iNum].Name := sName;
       Plugin[iNum].Handle := PackageHandle;
       Plugin[iNum].Menu := MenuPlugIn;
       Plugin[iNum].Created := False;
       Plugin[iNum].FrameLoaded := False;
      // récupération du plugin
       CreatePlugin := GetProcAddress(PackageHandle,'CreatePlugin');
       if assigned(CreatePlugin) then
         Plugin[iNum].Plug := CreatePlugin;
    end;

    Pas de problème à ce niveau, les multiples plugins se chargent correctement, en pas à pas, je ne rencontre aucun soucis et je vois même en passant le curseur sur Plugin[].Menu le contenu de cette structure.

    Le problème ce passe plus loin lorsque je veux créer les boutons dans l'objet TCategorieButton

    Dès que je fais appel dans ma procédure

    Code delphi : 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
     
      // création des boutons
      j := 0;
      for i := low(plugin) to high(plugin) do
      begin
        sTextTemp := Plugin[i].Menu.Categorie.Caption;
      // L'erreur à la ligne en dessous
        if  CategoryButtons1.Categories.Count > 0 then
        begin
          if CategoryButtons1.Categories.IndexOf(PlugIn[i].Menu.Categorie.Caption) <> -1 then
            Categ := CategoryButtons1.Categories.Items[j]
          else begin
            Categ := CategoryButtons1.Categories.Insert(0);
          end;
        end else
          Categ := CategoryButtons1.Categories.Insert(0);

    J'ai essayé plusieurs choses et dès que j'utilise un objet dans cette procedure j'ai une violation d'accès (J'ai mis un simple mémo.lines.add d'un valeur du Plugin[].Menu et ca plante ) et les objets existent bien dans ma form

    Si quelqu'un voit pourquoi il y a cette violation.

    Merci.

  2. #2
    Membre chevronné

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    1 519
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 519
    Points : 2 153
    Points
    2 153
    Billets dans le blog
    1
    Par défaut
    Mmmmh est-ce que le fait que tu passes par des variables locales pour stocker les pointeurs vers tes méthodes ne poserait-il pas problème ? Du genre à la sortie de la procédure les variables sont détruites et du coup les valeurs dans le tableau deviennent inconsistantes ?

    Par ailleurs dans ton second morceau de code tu as mis que l'erreur se produit à l'erreur en-dessous, or auparavant tu as récupéré le nom du Menu.Categorie ce qui est en contradiction avec le fait que tu dises que rien ne fonctionne dès que tu fais appel à la méthode normalement (peut-être une erreur de recopie du code ici).

  3. #3
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 235
    Points : 8 504
    Points
    8 504
    Par défaut
    Citation Envoyé par Aka Guymelef Voir le message
    Mmmmh est-ce que le fait que tu passes par des variables locales pour stocker les pointeurs vers tes méthodes ne poserait-il pas problème ? Du genre à la sortie de la procédure les variables sont détruites et du coup les valeurs dans le tableau deviennent inconsistantes ?

    Par ailleurs dans ton second morceau de code tu as mis que l'erreur se produit à l'erreur en-dessous, or auparavant tu as récupéré le nom du Menu.Categorie ce qui est en contradiction avec le fait que tu dises que rien ne fonctionne dès que tu fais appel à la méthode normalement (peut-être une erreur de recopie du code ici).
    Je me suis peut être mal exprimé

    Plugin est un tableau de structure global

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    type TPlugInsStruct = record
      Handle : integer;
      Plug : IPlugin;
      PlugCfg : IPluginCFG;
      Name : string;
      Menu : TMenuPlugin;
      Created : Boolean;
      FrameLoaded : Boolean;
    end;
    Et toutes les variables locales sont transférés vers la structure, il n'y a pas de problème avec cela.
    J'arrive parfaitement à charger tout mes plugins.
    Le problème survient à chaque fois que je fais appel au CategorieButton, qui me génère une violation d'accès pour je ne sais quel raison

    A la place du CategorieButton, j'ai mis un mémo pour voir si le bug ne venait pas en fait des variables de Plugin[].Menu et j'ai eu aussi une violation d'accès.

    Puis j'ai testé avec ShowMessage et la pas de problème

    En fait toute la partie plugin fonctionne parfaitement, mais c'est la partie création de boutons qui plante dès que je fais appel à CategoryButtons1.

    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
     
    procedure TfrmMain.CreateButton;
    var
      i,j : integer;
      bSwap : Boolean;
      PlugTemp : TPlugInsStruct;
      Categ : TButtonCategory;
      Button : TButtonItem;
    begin
      // tri du tableau
      bSwap := True;
      While bSwap do
      begin
        bSwap := False;
        for i := low(plugin) to high(plugin) - 1 do
        begin
          if (Plugin[i].Menu.Categorie.Position < Plugin[i + 1].Menu.Categorie.Position) or
          ((Plugin[i].Menu.Categorie.Position = Plugin[i + 1].Menu.Categorie.Position) and
          (Plugin[i].Menu.button.position > Plugin[i + 1].Menu.Button.Position)) then
          begin
            PlugTemp := Plugin[i];
            Plugin[i] := Plugin[i+1];
            Plugin[i+1] := PlugTemp;
            bSwap := true;
          end;
        end; // for
      end; // while
     
      // création des boutons
      j := 0;
      for i := low(plugin) to high(plugin) do
      begin
        // Création de la catagorie
        if  CategoryButtons1.Categories.Count > 0 then
        begin
          if CategoryButtons1.Categories.IndexOf(PlugIn[i].Menu.Categorie.Caption) <> -1 then
            Categ := CategoryButtons1.Categories.Items[j]
          else begin
            Categ := CategoryButtons1.Categories.Insert(0);
          end;
        end else
          Categ := CategoryButtons1.Categories.Insert(0);
     
     
        With Categ do
        begin
          Color := PlugIn[i].Menu.Categorie.Color;
          GradientColor := PlugIn[i].Menu.Categorie.GradientColor;
          TextColor := PlugIn[i].Menu.Categorie.TextColor;
          Caption := PlugIn[i].Menu.Categorie.Caption;
        end;
     
        if Plugin[i].Menu.Bitmap <> nil then
          With ilMain do
          begin
            Masked := True;
            AddMasked(Plugin[i].Menu.Bitmap, Plugin[i].Menu.Bitmap.canvas.Pixels[0,0]);
            Plugin[i].Menu.ImageIndex := Count -1;
          end;
        // Création du bouton dans la catégorie
        Button := Categ.Items.Add;
        Button.Caption := Plugin[i].Menu.Button.caption;
        Button.Hint := IntToStr(i);
        Button.ImageIndex := Plugin[i].Menu.ImageIndex;
      end;

  4. #4
    Membre chevronné

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    1 519
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 519
    Points : 2 153
    Points
    2 153
    Billets dans le blog
    1
    Par défaut
    Donc si je comprends bien, l'erreur se produit sur l'instruction "CategoryButtons1.Categories.Count" n'est-ce pas ? Néanmoins la question qui reste entière pour moi : CategoryButtons1 Kézaco

    Par ailleurs tu parles CategorieButton mais ce n'est pas une classe de base de Delphi. Du coup j'imagine que c'est ta propre classe, et si l'erreur était dedans ou comment CategoryButtons1 est instancié (j'ai l'impression que c'est déposé sur une fiche vu le nom mais bon...)

  5. #5
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 235
    Points : 8 504
    Points
    8 504
    Par défaut
    Citation Envoyé par Aka Guymelef Voir le message
    Donc si je comprends bien, l'erreur se produit sur l'instruction "CategoryButtons1.Categories.Count" n'est-ce pas ? Néanmoins la question qui reste entière pour moi : CategoryButtons1 Kézaco

    Par ailleurs tu parles CategorieButton mais ce n'est pas une classe de base de Delphi. Du coup j'imagine que c'est ta propre classe, et si l'erreur était dedans ou comment CategoryButtons1 est instancié (j'ai l'impression que c'est déposé sur une fiche vu le nom mais bon...)
    Le CategorieButton est un objet rajouté avec Delphi 2005 (Celui qui permet de gérer la palette d'outils) et c'est une classe de base à partir de D2005
    De toutes façon que j'utilise un CategorieButton , un TMemo, une TListBox ou tout autres objets déposés sur ma form principale j'ai une violation d'accès.

  6. #6
    Membre chevronné

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    1 519
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 519
    Points : 2 153
    Points
    2 153
    Billets dans le blog
    1
    Par défaut
    Ha d'accord moi je suis encore qu'un rétrograde sous Delphi 7, c'est pour ça que l'aide ne m'en apprenait pas plus sur cette classe

    Sinon quand tu exécutes en mode débug et que tu inspecte CategoryButton1, ça donne quoi ? Par ailleurs à quel moment est appelé la méthode CreateButton ?

    EDIT : je viens de revoir le tuto ici et dedans l'affectation de la variable contenant la procédure extraite de la librairie se fait en utilisant l'opérateur @ devant la variable. Alors peut-être qu'en D2005 ça ne se fait plus comme ça mais ça a peut-être une importance ?

  7. #7
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 235
    Points : 8 504
    Points
    8 504
    Par défaut
    Code Delphi : 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
    33
    34
    35
    36
    37
     
    procedure TfrmMain.LoadAllPlugin;
    var
      i : integer;
      SR : TSearchRec;
    begin
      frmSplash := TfrmSplash.Create(self);
      With frmSplash do
      try
        Show;
        if FindFirst(GAPPPBPL + '*.bpl',faAnyFile,SR) = 0 then
        begin
          iPluginNb := 0;
          LoadPackages(iPluginNb,GAPPPBPL + SR.Name);
          SFLBL3.Caption := ('Ouverture du plugin : ' + SR.Name);
          Application.ProcessMessages;
          While FindNext(SR) = 0 do
          begin
            inc(iPluginNb);
            LoadPackages(iPluginNb,GAPPPBPL + SR.Name);
            SFLBL3.Caption := ('Ouverture du plugin : ' + SR.Name);
            Application.ProcessMessages;
          end;
        end;
        FindClose(SR);
       // Par la l'appel :p
       CreateButton;
        for i := low(plugin) to high(plugin) do
          Memo1.Lines.Add(plugin[i].Name + ' : ' + plugin[i].Menu.Version
          + '-' + Plugin[i].Menu.Categorie.Caption
          + '/' + Plugin[i].Menu.Button.Caption
          + '/' + IntToStr(Plugin[i].Menu.Categorie.Position));
      finally
        Release;
      end;
      frmSplash.Release;
    end;

    Ce que je ne comprend pas, c'est que j'utilise la même solution dans un autre logiciel est cela fonctionne parfaitement :/

  8. #8
    Membre chevronné

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    1 519
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 519
    Points : 2 153
    Points
    2 153
    Billets dans le blog
    1
    Par défaut
    Je reprends mon edit :

    je viens de revoir le tuto ici et dedans l'affectation de la variable contenant la procédure extraite de la librairie se fait en utilisant l'opérateur @ devant la variable. Alors peut-être qu'en D2005 ça ne se fait plus comme ça mais ça a peut-être une importance ?
    De même pour voir si on a bien récupérer la méthode on teste <> NIL au lieu de Assigned (qui je crois va entraîner l'appel de la méthode justement) => fuite de mémoire ?

    En outre j'ai l'impression que tu fais deux fois Release sur ton frmSplash, une fois dans le finally et une autre juste après.

  9. #9
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 235
    Points : 8 504
    Points
    8 504
    Par défaut
    Citation Envoyé par Aka Guymelef Voir le message
    Je reprends mon edit :

    je viens de revoir le tuto ici et dedans l'affectation de la variable contenant la procédure extraite de la librairie se fait en utilisant l'opérateur @ devant la variable. Alors peut-être qu'en D2005 ça ne se fait plus comme ça mais ça a peut-être une importance ?
    De même pour voir si on a bien récupérer la méthode on teste <> NIL au lieu de Assigned (qui je crois va entraîner l'appel de la méthode justement) => fuite de mémoire ?

    En outre j'ai l'impression que tu fais deux fois Release sur ton frmSplash, une fois dans le finally et une autre juste après.
    Attention , ce ne sont pas des DLL que j'utilise, mais des packages + des interfaces, ca ne fonctionne pas de la même manière.

  10. #10
    Membre chevronné

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    1 519
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 519
    Points : 2 153
    Points
    2 153
    Billets dans le blog
    1
    Par défaut
    Je suppose que non mais j'imagine que l'appel à LoadAllPlugin n'est pas fait avant la création complète de la fiche, au moment où les composants déposés ne seraient pas encore disponibles ?

  11. #11
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Salut

    Ta variable J me gène un peu !!

    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
     
    // création des boutons
      j := 0;
      for i := low(plugin) to high(plugin) do
      begin
        // Création de la catagorie
        if  CategoryButtons1.Categories.Count > 0 then
        begin
          if CategoryButtons1.Categories.IndexOf(PlugIn[i].Menu.Categorie.Caption) <> -1 then
            Categ := CategoryButtons1.Categories.Items[j]
          else begin
            Categ := CategoryButtons1.Categories.Insert(0);
          end;
        end else
          Categ := CategoryButtons1.Categories.Insert(0);
     
      // ...
    Je verrais plus comme ça:
    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
     
      // Création des boutons
      for I := Low(Plugin) to High(Plugin) do
      begin
        // Création de la catégorie
        with CategoryButtons1.Categories do
        begin
          // IndexOf renvoie -1 si Count = 0
          J := IndexOf(Plugin[I].Menu.Categorie.Caption);
          if J <> - 1 then
            Categ := Items[J]
          else
            Categ := Insert(0);
        end;
     
      // ...
    Ceci n'explique pas forcément l'AV. Vérifie ton tri peut-être en début de procédure.

    @+ Claudius

  12. #12
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 235
    Points : 8 504
    Points
    8 504
    Par défaut
    Citation Envoyé par Aka Guymelef Voir le message
    Je suppose que non mais j'imagine que l'appel à LoadAllPlugin n'est pas fait avant la création complète de la fiche, au moment où les composants déposés ne seraient pas encore disponibles ?
    Normalement dans le OnCreate les composants sont déjà créés et donc il ne devrait pas y avoir de soucis.
    J'ai même essayé en mettant l'appel de la procédure dans le DPR, mais je me retrouve avec le même problème

    Citation Envoyé par Cl@udius Voir le message

    Ta variable J me gène un peu !!
    Le code est pas fini, je fais quelques arrangements en même temps

    Citation Envoyé par Cl@udius Voir le message
    Ceci n'explique pas forcément l'AV. Vérifie ton tri peut-être en début de procédure.
    Vu que pour le moment je n'ai qu'un seul plugin, il ne passe pas dans le tri, de plus le problème est uniquement quand je fais appel à des objets dans cette procédure, ailleurs ils fonctionnent

    [Edit]
    En mettant l aprocédure CreateButtons dans le OnShow, ca fonctionne correctement

  13. #13
    Membre chevronné

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    1 519
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 519
    Points : 2 153
    Points
    2 153
    Billets dans le blog
    1
    Par défaut
    Mmmh de mémoire je sais que si je veux travailler avec les composants visuels déposés sur la fiche, il fallait que je me positionne à minima en override de la méthode Loaded du TForm et après son inherited. OnCreate est peut-être appelé avant cet appel (bien noter aussi que cet appel à l'évènement est fait à un moment différent suivant comment est positionné la propriété OldCreateOrder).

Discussions similaires

  1. Réponses: 16
    Dernier message: 19/03/2009, 15h08
  2. Réponses: 1
    Dernier message: 02/08/2006, 17h37
  3. requete / violation d'accès
    Par marie253 dans le forum Bases de données
    Réponses: 4
    Dernier message: 13/08/2004, 13h29
  4. Violation d'acces apres Execute
    Par SegmentationFault dans le forum Connexion aux bases de données
    Réponses: 6
    Dernier message: 10/08/2004, 16h23
  5. Violation d'accès apres Close
    Par SegmentationFault dans le forum Bases de données
    Réponses: 3
    Dernier message: 05/07/2004, 16h46

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