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 :

interface dans un variant : libération de la référence [FAQ]


Sujet :

Langage Delphi

  1. #1
    Membre actif
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    292
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 292
    Points : 222
    Points
    222
    Par défaut interface dans un variant : libération de la référence
    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
     
    ITest = interface
            ['{8BAC43A7-9083-4736-8912-708AF5D684A7}']
            function BonAlors: Boolean;
    end;
     
    TTest = class(TInterfacedObject, ITest)
            function BonAlors: Boolean;
     
            destructor Destroy; override;
    end;
     
     
     
    { TTest }
     
    function TTest.BonAlors: Boolean;
    begin
            result := True;
    end;   
     
    destructor TTest.Destroy;
    begin
            Form1.Memo1.Lines.Add('Destr');
            inherited;
    end;
    ensuite

    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
     
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
            VarTest: Variant;
            IntTest, IntTest2: ITest;
            testu: IUnknown;
    begin
            Memo1.Clear;
     
            IntTest := TTest.Create;
     
            VarTest := IntTest as IUnknown;
     
            IntTest := nil;    
            VarTest := Unassigned;
     
            Memo1.Lines.Add('fin');
    end;
    je voudrait qu'il affiche 'destroy' avant d'afficher 'fin', cependant, VarTest := Unassigned ne semble pas provoquer la libération de la référence. Il faut attendre de sortir de la fonction pour que 'destroy' soit affiché.

    Qqn a une explication ?

  2. #2
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Points : 15 060
    Points
    15 060
    Billets dans le blog
    1
    Par défaut
    Salut,
    le code est correcte mais il me semble que tu supposes que le compteur de référence devrait être égale à 2 après l'appel de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
        VarTest := IntTest as IUnknow;
    mais en tracant on s'aperçoit que le compteur FrefCount vaut 3 tout simplement parce que l'opérateur as appel QueyInterface et donc incrémente le compteur de référence.
    Au vu de ton code l'appel de as ne semble pas justifié, ce code affiche bien 'destroy' avant 'fin'.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
        VarTest := IntTest;
    A partir du moment ou IntTest est une interface, le code IntTest := TTest.Create renvoi une interface qui par défaut implèmente IUnknow.

    Qq peut-il confimer ?

  3. #3
    Membre actif
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    292
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 292
    Points : 222
    Points
    222
    Par défaut
    j'avais eu un problème de compilation et c'est pourquoi j'avais cru nécessaire de mettre as IUnknown. Je viens de réessayer, ça fonctionne. J'avais du rater quelque chose d'autre.

    hyper bizarre quand même ce problème de comptage de référence.

    A partir du moment ou IntTest est une interface, le code IntTest := TTest.Create renvoi une interface qui par défaut implèmente IUnknow.

    Qq peut-il confimer ?
    je confirme sans hésiter.

  4. #4
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Points : 15 060
    Points
    15 060
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Bruno75
    hyper bizarre quand même ce problème de comptage de référence.
    Pas vraiment d'aprés la doc en ligne (D6) :
    Renvoie une référence à l'interface spécifiée, si l'objet supporte cette interface.

    type HResult = Longint;
    function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;

    Description

    QueryInterface vérifie si l'objet qui implémente cette interface prend en charge l'interface spécifiée par IID. Si tel est le cas, QueryInterface

    incrémente le compteur de références.
    définit le paramètre Obj afin qu'il pointe sur une instance de l'interface spécifiée.
    renvoie 0 pour confirmer la réussite de l'opération.

    Si l'objet ne supporte pas l'interface, QueryInterface renvoie un code d'erreur non nul tel que E_NoInterface.

  5. #5
    Membre actif
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    292
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 292
    Points : 222
    Points
    222
    Par défaut
    si si c'est bizarre. d'ailleurs, si tu remplaces mon variant par une interface IUnknown et que tu laisses le as le destroy interviendra bien avant le retour de la fonction.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
     
            VarTest: IUnknown;
            IntTest, IntTest2: ITest;
            testu: IUnknown;
    begin
            Memo1.Clear;
     
            IntTest := TTest.Create;
     
            VarTest := IntTest as IUnknown;
     
            IntTest := nil;    
            VarTest := nil;
    ça marche.

  6. #6
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Points : 15 060
    Points
    15 060
    Billets dans le blog
    1
    Par défaut
    Oui j'avais fais le test mais la trace du comportement d'un variant est un peu plus complexe

  7. #7
    Membre actif
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    292
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 292
    Points : 222
    Points
    222
    Par défaut
    un bon gros bug de Delphi quoi.
    en tout cas merci tu m'as débeloker.

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 03/07/2012, 21h20
  2. Copier un String dans un variant
    Par foued_scorpion dans le forum Visual C++
    Réponses: 2
    Dernier message: 03/11/2006, 23h35
  3. Ajouter une interface dans une classe
    Par Battosaiii dans le forum Langage
    Réponses: 2
    Dernier message: 03/10/2006, 14h02
  4. [SWING] Mise a jour de l'interface dans les événements
    Par woods dans le forum EDT/SwingWorker
    Réponses: 3
    Dernier message: 23/11/2005, 15h46
  5. Réponses: 8
    Dernier message: 26/08/2004, 18h59

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