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 :

objet pour bpl


Sujet :

Langage Delphi

  1. #1
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 387
    Points : 2 999
    Points
    2 999
    Par défaut objet pour bpl
    Salut les gens du dimanche

    ça sent les vacances mais je sèche.
    J'ai un BPL qui contient la fonction suivante:

    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
     
    procedure EnregistreListeTables(Connexion: TADOConnection);stdcall;
    var
      Table: string;
      Tables: TStringList;
      Str: TStringStream;
    begin
      Str := TStringStream.Create;
      Tables := TStringList.Create;
      Table := Connexion.ConnectionString;
      Str.WriteString(Table);
      Connexion.GetTableNames(Tables, False);
      for Table in Tables do
        Str.WriteString(Table + #10#13);
      Str.SaveToFile('C:\fichiers\ListeTables.txt');
      Str.Free;
      Tables.Free;
    end;
    L'appel se fait 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
    17
    18
    19
    20
     
    var
      PackageModule: HModule;
      Fonction: procedure (Connexion: TADOConnection);
    begin
      PackageModule := LoadPackage('Editions.bpl');
      if PackageModule <> 0 then
      begin
        @Fonction := GetProcAddress(PackageModule, 'EnregistreListeTables');
        if @Fonction = nil then
          ShowMessage('La DLL ne contient pas la fonction "EnregistreListeTables"')
        else
        begin
          ADOConnection1.Connected := True;
          Fonction(ADOConnection1);
          ADOConnection1.Connected := False;
        end;
        UnloadPackage(PackageModule);
      end;
    end;

    La fonction est bien appelée mais je ramasse une grosse violation d'accès sur

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Connexion.GetTableNames(Tables, False);
    Comme si l'objet ne passait pas de l'exe au bpl.

    Qu'est-ce que j'ai oublié ?


    Papy !

  2. #2
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 693
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 693
    Points : 13 128
    Points
    13 128
    Par défaut
    Tu n'as rien oublié mais LoadPackage ne diffère pas beaucoup de LoadLibrary. La grande différence (la seule ?) est que LoadPackage passe à travers les blocs d’initialisation des unités (initialization propres à Delphi) et finalisation au déchargement (UnloadPackage). Pour que tes objets soient pleinement reconnus à l'exécution, il faut que l'application soit liée statiquement au package. Sinon tu te retrouves avec les mêmes problèmes de récupération d'instances que depuis une simple librairie (dll) chargée par LoadLibrary.

  3. #3
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 387
    Points : 2 999
    Points
    2 999
    Par défaut
    Comprends pas !
    Les BPL sont quand même bien mieux intégrés que les Dll.
    Je ne suis pas dans le cas où je voudrais utiliser un objet TADOConnection contenu dans mon bpl mais utiliser l'objet dans le bpl après l'avoir passé en paramètre.
    Mon objet existe bien au moment où je l'envoie.
    Ok que pour une dll ce serait plus compliqué !

    D'ailleurs, en écrivant ce message il me vient une idée ....

    ....


    Je viens de virer le stdcall en fin de déclaration de ma procédure et ça fonctionne

  4. #4
    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 : 54
    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 445
    Points
    28 445
    Par défaut
    je n'ai pas mon livre sous la main, mais Olivier DAHAN avait fait un chapitre sur les packages et leur chargement dynamique si mon souvenir est bon.

    personnellement je n'ai jamais réellement étudié la question...comme je le dis à chaque fois, si je devais déporter des objets dans des DLL/packages je le ferais via des Interfaces
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  5. #5
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 387
    Points : 2 999
    Points
    2 999
    Par défaut
    Et dans ce cas précis, tu coderais çà comment ?
    Je ne vois pas comment utiliser une interface dans ce cas précis.
    Autant implémenter une classe dans le bpl (dll) , et définir faire une fonction qui renverrait une interface sur un objet de cette classe, je vois comment faire.
    Mais là, dans mon bpl, je mets quoi ? une classe qui contient un TADOconnection avec une interface pour l'échange ?

  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 : 54
    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 445
    Points
    28 445
    Par défaut
    ben c'est pas très compliqué en fait

    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
     
     
    type 
      IADOConnection = interface
        function ConnectionStr: PChar;
        function GetTableCount: Integer;
        function GetTableName(Index: Integer): PChar;
      end;
     
    procedure EnregistreListeTables(Connexion: IADOConnection);stdcall;
    var
      Table: string;
      //Tables: TStringList;
      Str: TStringStream;
      Count, Index: Integer:
    begin
      Str := TStringStream.Create;
      Tables := TStringList.Create;
      Table := Connexion.ConnectionStr;
      Str.WriteString(Table);
      //Connexion.GetTableNames(Tables, False);
      Count := Connexion.getTableCount;
      for Index := 0 to Count - 1 do 
        Str.WriteString(Connexion.getTableName(Index) + #13#10);
      //for Table in Tables do
      //  Str.WriteString(Table + #10#13);
      Str.SaveToFile('C:\fichiers\ListeTables.txt');
      Str.Free;
      Tables.Free;
    end;
    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
     
    type
      TMyADOConnection = class(TADOConnection, IADOConnection)
        temp: string;
        list : TStringList;
        function ConnectionStr: PChar;
        function GetTableCount: Integer;
        function GetTableName(Index: Integer): PChar;
        destructor Destroy; override;
      end;
     
        function TMyADOConnection.ConnectionStr: PChar;
        begin
           temp := ConnectionStriing;
           Result := PChar(temp);
        end;
     
        function TMyADOConnection.GetTableCount: Integer;
        begin
          if list = nil then
          begin
            list := TStringList.Create;
            GetTableNames(list, False);
          end;
          Result := list.count;
        end;
     
        function TMyADOConnection.GetTableName(Index: Integer): PChar;
        begin
         temp := list[Index];
         Result := PChar(temp);
        end;
     
        destructor TMyADOConnection.Destroy;
        begin
         list.Free;
         inherited; 
       end;
    NB: j'ai codé vite fait une méthode pour retourner des PChar sans perte de mémoire, il y a d'autres approches possibles
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  7. #7
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 387
    Points : 2 999
    Points
    2 999
    Par défaut
    Ok, je vois le principe dans cette optique là. Mais ...

    Je vais décrire plus précisément ce que je voulais faire parce que je pense que l'interface pour moi n'aurait pas grande utilité.
    J'ai 3 applications (que j'ai reprises, et pas faites moi-même).
    Chacune réalise par exemple des éditions de rapport avec QuickReport.
    Les rapports sont liés à des TADOQuery sur les TForm contenant les rapports.
    Problème, les 3 programmes différents utilisent du (presque) copier-coller de code source.
    Donc, j'essaie peu à peu d'unifier tout ça non pas en mettant du code source commun mais plutôt avec un bpl qui réalisera ces éditions.
    Le bpl contient les modèles quickreport avec les TQuery déjà définis.
    Il ne manque que le TADOConnection.
    Donc, à l'appel de la fonction du bpl, je passe le TADOConnection en paramètre pour l'associer au TADOQuery et lancer la génération.
    J'aurais pu créer un autre TADOQuery dans le bpl et passer une simple chaîne de connexion mais je pensais éviter ce doublon.

    L'exemple que tu fourni utilise des fonctions créées pour l'interface. Mais ne permet pas de passer l'objet lui-même.

    Mais du coup, merci ... parce que j'ai mieux compris ce que tu préconises si souvent et que je mettrai en pratique quand ce sera utile.

    Reste à savoir pourquoi la suppression du stdcall dans la déclaration de la procédure à résolu le problème.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Component] [Framework] Y a t'il un objet pour le NNTP ?
    Par backseatgreg dans le forum Framework .NET
    Réponses: 3
    Dernier message: 31/12/2007, 17h08
  2. [Tkinter] sélection d'objet pour déplacement
    Par airod dans le forum Tkinter
    Réponses: 7
    Dernier message: 18/05/2006, 09h40
  3. Sélection d'objets pour un logiciel de type AutoCAD
    Par loran4444 dans le forum C++Builder
    Réponses: 15
    Dernier message: 09/03/2005, 19h23
  4. Utilisation d'objets pour imprimer
    Par alainvh dans le forum Composants VCL
    Réponses: 3
    Dernier message: 02/12/2004, 10h25
  5. [debutant][JNI]Stocker des objet pour les rappeler plus tard
    Par Celenor dans le forum Entrée/Sortie
    Réponses: 7
    Dernier message: 28/03/2004, 01h28

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