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

Delphi Discussion :

Soap HTTPRIO libération mémoire


Sujet :

Delphi

  1. #1
    Membre confirmé Avatar de Galet
    Homme Profil pro
    Consultant/Programmeur Robotique industrielle
    Inscrit en
    Mars 2010
    Messages
    323
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Consultant/Programmeur Robotique industrielle

    Informations forums :
    Inscription : Mars 2010
    Messages : 323
    Points : 484
    Points
    484
    Par défaut Soap HTTPRIO libération mémoire
    Bonjour à tous,
    Après beaucoup de recherches, je n'arrive pas à supprimer l'exception pour défaut de pointer à la fermeture de l'application. Il s'agit d'une application Soap (sous Delphi XE2) avec un objet THTTPRIO déposé sur la fiche principale. Pour simplifié, j'ai préparer une appli ultra light :
    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
    66
    67
    68
    69
     
     <script type="text/delphi">
     <!--
    unit MainUnit;
     
    interface
     
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Soap.InvokeRegistry, Vcl.StdCtrls,
      Soap.Rio, Soap.SOAPHTTPClient,
     
      cs8serverv0;
     
    type
      TForm1 = class(TForm)
        BuClose: TButton;
        BuConnect: TButton;
        HTTPRIO1: THTTPRIO;
        LaServer: TLabel;
        procedure BuCloseClick(Sender: TObject);
        procedure BuConnectClick(Sender: TObject);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
     
    var
      Form1: TForm1;
      Server_V0 : CS8ServerV0PortType;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm1.BuCloseClick(Sender: TObject);
    begin
      Close;
    end;
     
    procedure TForm1.BuConnectClick(Sender: TObject);
    Var
      fGetSoapServerVersionResponse: getSoapServerVersionResponse;
      fGetSoapServerVersion: getSoapServerVersion;
    begin
      // Ouverture du serveur
      Server_V0 := GetCS8ServerV0PortType(false, 'http://127.0.0.1:851/', HTTPRIO1);
     
      fGetSoapServerVersionResponse := getSoapServerVersionResponse.Create;
      fGetSoapServerVersion := getSoapServerVersion.Create;
     
      fGetSoapServerVersion.cltName := 'Me';
      fGetSoapServerVersion.cltVersion := '0';
     
      try
        fGetSoapServerVersionResponse := Server_V0.getSoapServerVersion
          (fGetSoapServerVersion);
      finally
        LaServer.Caption := fGetSoapServerVersionResponse.server.Version;
     
        fGetSoapServerVersionResponse.Free;
        fGetSoapServerVersion.Free;
      end;
    end;
     
    end.
     //-->
     </script>
    L'objet HTTPRIO est, d'après mes lectures, normalement libéré par le parent : Form1 mais cela ne semble pas être le cas.
    J'ai, malgré tout, essayé de libérer HTTPRIO1 avec free ou destroy sans succès. Pour éviter ce défaut, j'ai réécrit mon appli en créant un objet THTTPRIO sans parent mais, dans cette configuration, je n'ai pas réussi à passer une Entête sans problème.

    Merci pour votre aide.
    Galet

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 621
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 621
    Points : 25 321
    Points
    25 321
    Par défaut
    Tu as un Create en trop, celui de fGetSoapServerVersionResponse

    D'ailleurs, je l'écrirais ainsi pour que le try finally soit bien place

    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
    procedure TForm1.BuConnectClick(Sender: TObject);
    Var
      fGetSoapServerVersionResponse: getSoapServerVersionResponse;
      fGetSoapServerVersion: getSoapServerVersion;
    begin
      // Ouverture du serveur
      Server_V0 := GetCS8ServerV0PortType(false, 'http://127.0.0.1:851/', HTTPRIO1);
     
      fGetSoapServerVersion := getSoapServerVersion.Create;
      try
        fGetSoapServerVersion.cltName := 'Me';
        fGetSoapServerVersion.cltVersion := '0';
     
     
        fGetSoapServerVersionResponse := Server_V0.getSoapServerVersion(fGetSoapServerVersion);
        try
          LaServer.Caption := fGetSoapServerVersionResponse.server.Version;
        finally
           fGetSoapServerVersionResponse.Free;
        end;
      finally    
        fGetSoapServerVersion.Free;
      end;
    end;
    enfin, en D7, je n'avais pas de composant HTTPRIO posé sur une forme ou un DataModule, voici ce que j'ai pour un client WS
    Je n'ai plus le code mais j'ai retrouve des fragments sur le net, je pense avoir former un tout cohérent

    pour l'ajout d'entête, ceci pourrait t'interesser [D7] WebService et HTTPWebNode.UserName\PassWord

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    class procedure TXXXHelper.HTTPReqResp_WSBeforePost(const HTTPReqResp: THTTPReqResp; Data: Pointer);
    var
      s: string;
    begin
      s := 'la valeur a ajouté';
       if not HttpAddRequestHeaders(Data, PChar(s), Length(s), HTTP_ADDREQ_FLAG_ADD) then
        ManageError('HttpAddRequestHeaders', GetLastError());
    end;
    une variante de GetCS8ServerV0PortType avec un objet interne
    XXXWsPortType est une interface et THTTPRIO gère le compteur de référence pour la libération automatique
    N'utilise pas THTTPRIO directement mais UNIQUEMENT l'interface XXXWsPortType

    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
    function GetXXXWsPortType(UseWSDL: Boolean; Addr: string; OnSOAPHTTPException: TXXXWebServiceSOAPHTTPExceptionEvent): XXXWsPortType;
    const
      defWSDL = 'http://XXX.wsdl';
      defURL  = 'http://XXX.php';
      defSvc  = 'XXXWs';
      defPrt  = 'XXXWsPort';
    var
      RIO: THTTPRIO;
    begin
      Result := nil;
      if (Addr = '') then
      begin
        if UseWSDL then
          Addr := defWSDL
        else
          Addr := defURL;
      end;
      RIO := THTTPRIO.Create(nil);
      try
        RIO.HTTPWebNode := THTTPReqResp_XXXWebService.Create(RIO);
        THTTPReqResp_XXXWebService(RIO.HTTPWebNode).OnSOAPHTTPException := OnSOAPHTTPException;
        THTTPReqResp_XXXWebService(RIO.HTTPWebNode).OnBeforePost := TXXXHelper.HTTPReqResp_WSBeforePost;
     
     
        Result := (RIO as XXXWsPortType);
        if UseWSDL then
        begin
          RIO.WSDLLocation := Addr;
          RIO.Service := defSvc;
          RIO.Port := defPrt;
        end else
          RIO.URL := Addr;
      finally
        if (Result = nil) then
          RIO.Free;
      end;
    end;

  3. #3
    Membre confirmé Avatar de Galet
    Homme Profil pro
    Consultant/Programmeur Robotique industrielle
    Inscrit en
    Mars 2010
    Messages
    323
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Consultant/Programmeur Robotique industrielle

    Informations forums :
    Inscription : Mars 2010
    Messages : 323
    Points : 484
    Points
    484
    Par défaut
    Merci ShaiLeTroll,
    Je tente ça avant de clore le sujet.

  4. #4
    Membre confirmé Avatar de Galet
    Homme Profil pro
    Consultant/Programmeur Robotique industrielle
    Inscrit en
    Mars 2010
    Messages
    323
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Consultant/Programmeur Robotique industrielle

    Informations forums :
    Inscription : Mars 2010
    Messages : 323
    Points : 484
    Points
    484
    Par défaut

    Après tentative (copier-coller de ta routine), en supprimant donc le create de trop et en replaçant correctement les exceptions (merci, au passage pour le conseil qui va me permettre de rectifier d'autres erreurs), j'ai toujours le même défaut à la fermeture :
    Nom : Capture.PNG
Affichages : 494
Taille : 17,8 Ko

    Voici le code tenté (sans succès) avant la fermeture de l'appli :
    //Server_V0 := nil;
    //HTTPRIO1.Free;
    //HTTPRIO1.Destroy;

    Si à l'appel de GetCS8ServerV0PortType, je ne fais pas référence à HTTPRIO1,je n'ai pas ce défaut de pointer.

    Je suis persuadé que la solution est évidente mais...

    Merci pour ton aide.
    Galet

  5. #5
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 621
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 621
    Points : 25 321
    Points
    25 321
    Par défaut
    Je pense qu'il y a un conflit de libération entre le Owner (Form) et le compteur de référence.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Server_V0 := GetCS8ServerV0PortType(false, 'http://127.0.0.1:851/', HTTPRIO1);
    HTTPRIO1.Owner.RemoveComponent(HTTPRIO1);
    Attention le membre HTTPRIO1 après RemoveComponent ne sera plus référencé, il ne faudrait que gérer Server_V0
    J'ai ecrit une fonction ChangeOwnerKeepReference qui conserve la référence publiée malgré le RemoveComponent



    Sinon, n'utilise plus HTTPRIO1 mais un composant créé dynamiquement !
    Pour tes entêtes, tu dois pouvoir mettre en code ce que tu configures via l'IDE

  6. #6
    Membre confirmé Avatar de Galet
    Homme Profil pro
    Consultant/Programmeur Robotique industrielle
    Inscrit en
    Mars 2010
    Messages
    323
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Consultant/Programmeur Robotique industrielle

    Informations forums :
    Inscription : Mars 2010
    Messages : 323
    Points : 484
    Points
    484
    Par défaut
    Merci pour ton conseil.
    Je vais tenter les 2 pistes. L'appli avec un HTTPRIO créé dynamiquement serait aussi beaucoup plus propre. Je pense avoir lu (sur Développez et sur le web), a peut près tout ce qui est écrit à ce sujet, sans avoir trouvé de solution correcte. Mon appli commence à être efficace (Diagnostique d'application sur robot industriel) mais avoir ce défaut en fermant l'appli ne fait pas très pro...
    Il me reste aussi une amélioration à placer pour récupérer correctement la réponse Soap dans un buffer pChar. Pour le moment, j'enregistre la réponse dans un fichier pour le relire ensuite (pour le diag, c'est super mais côté efficacité, c'est pas terrible.

  7. #7
    Membre confirmé Avatar de Galet
    Homme Profil pro
    Consultant/Programmeur Robotique industrielle
    Inscrit en
    Mars 2010
    Messages
    323
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Consultant/Programmeur Robotique industrielle

    Informations forums :
    Inscription : Mars 2010
    Messages : 323
    Points : 484
    Points
    484
    Par défaut
    Bien vu ShaiLeTroll pour le problème de Owner.

    Je ne sais pas encore si la solution mise en place ne pose pas de problème mais elle semble résoudre mon problème.
    Pour éviter les problèmes de dé-référencement avec le RemoveComponent, je ne l'applique que juste avant de fermer la fiche. Comme ça, pas de problème pour continuer à utiliser HTTPRIO durant toute l'application, et plus d'exception à la clôture.

    Quand j'aurais un peu plus de temps, je me remettrais sur le défaut d'entête avec un HTTPRIO créé dynamiquement. Je ne manquerais pas d'ouvrir une discussion pour partager...

    Merci encore pour ton aide,

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

Discussions similaires

  1. Libération mémoire TSQLQuery
    Par obione dans le forum Bases de données
    Réponses: 9
    Dernier message: 28/03/2007, 10h02
  2. Problème de libération mémoire
    Par chrono23 dans le forum C++
    Réponses: 16
    Dernier message: 07/09/2006, 23h18
  3. Réponses: 3
    Dernier message: 14/03/2006, 05h19
  4. [COM] Libération mémoire
    Par MC2 dans le forum Bibliothèques et frameworks
    Réponses: 5
    Dernier message: 13/01/2006, 16h15
  5. FIREBIRD + APPLI EN C : Problèmes de libération mémoire
    Par lio33 dans le forum Connexion aux bases de données
    Réponses: 4
    Dernier message: 16/09/2005, 09h07

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