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

Web & réseau Delphi Discussion :

Violation d'accès avec JSON Array


Sujet :

Web & réseau Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre extrêmement actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2017
    Messages
    2 086
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2017
    Messages : 2 086
    Par défaut Violation d'accès avec JSON Array
    Bonjour,

    Dev en Delphi 10.4 pour Android: J'essaie de lire un JSON récupéré dans RESTRequest incluant plusieurs éléments dont un tableau.

    J'arrive à accéder à toutes les données de manière individuelle y compris les valeurs de la table mais quand je veux traiter le tableau comme un tableau, j'ai une erreur "violation d'accés mémoire..."


    Le code qui fonctionne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    JsonValue := TJSonObject.ParseJSONValue(JSONresponse_str);
     
    //Je récupère une valeur 'doc_id' qui est un élément de 'header', lui-même élément de 'v_data'
    str:=JsonValue.GetValue<string>('results[0].v_data.header.doc_id');  //JSON mgt  OK OK OK
     
    //Je récupère une valeur 'doc_line_id' qui est un élément du 1er enregistrement du tableau 'lines' dans 'v_data'
    str:=JsonValue.GetValue<string>('results[0].v_data.lines[0].doc_line_id');  //JSON mgt  OK OK OK
    Par contre, le moindre accès au tableau se termine par une "violation d'accès".

    J'ai essayé plusieurs approches du code comme par exemple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
      LJson :=  TJSonObject.ParseJSONValue(JSONresponse_str) as TJSONObject;
      LValues := LJson.Values['lines'] as TJSONArray;
     
      str:=IntToStr(LValues.Count);
    Cela va planter sur le "LValues.Count"

    Est-ce que qqn voit ce que je fais faux?

    Merci pour votre avis

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 912
    Par défaut
    Parce que tu tentes de récupérer lines comme s'il était à la racine du document ce qui d'après le chemin n'est pas le cas.

    Soit tu récupères nœud après nœud (results puis v_data puis enfin lines) soit tu travailles toujours avec chemin, quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    LValues := JsonValue.GetValue<TJSONArray>('results[0].v_data.lines');
    .

  3. #3
    Membre extrêmement actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2017
    Messages
    2 086
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2017
    Messages : 2 086
    Par défaut
    Citation Envoyé par Andnotor Voir le message
    Parce que tu tentes de récupérer lines comme s'il était à la racine du document ce qui d'après le chemin n'est pas le cas.

    Soit tu récupères nœud après nœud (results puis v_data puis enfin lines) soit tu travailles toujours avec chemin, quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    LValues := JsonValue.GetValue<TJSONArray>('results[0].v_data.lines');
    .
    Bien vu Andnotor mais ce n'est pas la solution à mon problème. J'ai tapé un peu vite ma question sans mettre le lien complet. Je réitère ma question:

    Il s'agit bien de

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    LValues := JsonValue.GetValue<TJSONArray>('results[0].v_data.lines');
    .

    Et dès que j'essaie d'accéder au Array, cela plante avec une erreur "access violation"!

    Tu dis de récupérer un noeud après l'autre. Avec un tableau 'lines" dont je ne connais pas le nombre de lignes qui le compose et dans l'impossibilité de connaître le nombre de lignes en accédant à l'array, je fais comment?

  4. #4
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 999
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    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 999
    Par défaut
    Essaye

    Violation d'accès à une adresse 00000000 ?
    Regarder en débogage la valeur ça ne serait pas une mauvaise idée.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var
      lines: System.JSON.TJSONArray;
      line: System.JSON.TJSONValue;
    begin
      ...
      lines := (JsonValue as TJSONObject).GetValue('results[0].v_data.lines') as System.JSON.TJSONArray;
      for line in lines do
      begin
         ... line.GetValue('doc_line_id', 0);
     
      end;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  5. #5
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 999
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    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 999
    Par défaut
    Ah oui je ferais aussi un essai :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ShowMessage(JsonValue.GetValue<TObject>('results[0].v_data.lines').ClassName());
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  6. #6
    Membre extrêmement actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2017
    Messages
    2 086
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2017
    Messages : 2 086
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Ah oui je ferais aussi un essai :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ShowMessage(JsonValue.GetValue<TObject>('results[0].v_data.lines').ClassName());
    Excellente idée qui confirme qu'il s'agit bien d'un... TJSONArray!

    Un TJSONArray qu'il est impossible de toucher sous peine de plantage...


    Vu qu'il s'agit d'un JSON object récupéré via une procédure d'un serveur via REST et le processus faisant appel à RESTResponse et à un cliendataset pour récupérer la réponse, j'ai même essayé de libérer le RESTResponse et le clientdataset après avoir récupéré le JSON object (des fois qu'ils seraient concernés par le "accès à l'adresse ... en cours"), mais le problème subsiste.

    Je pense qu'il va falloir faire une croix sur la gestion des données via TJSONArray. Vu que je peux accéder aux données des différentes lignes du tableau une à une, je vais devoir bricoler une récupération à l'aveugle de chaque ligne du tableau et traiter l'erreur d'index qui va immanquablement se déclencher quand je vais essayer d'accéder à une ligne qui n'existe pas (et oui, je ne peux pas connaître le nombre exact de ligne puisque que tout accès au tableau y compris un simple TJSONArray.count m'est interdit).

  7. #7
    Membre extrêmement actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2017
    Messages
    2 086
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2017
    Messages : 2 086
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Essaye

    Violation d'accès à une adresse 00000000 ?
    Regarder en débogage la valeur ça ne serait pas une mauvaise idée.

    Le message d'erreur est du genre "Violation d'accès à l'adresse D218A71C, accès à l'adresse 0000008C en cours" mais les adresses peuvent changer d'une compilation à l'autre.

    D'autre part, je serai bien en peine de "regarder en debogage", il s'agit d'un développement Android et depuis Delphi Rio 10.3.3, le pack SDK Android ne fournit plus d'outil de debuggage comme c'était le cas avec l'excellent "Android monitor". J'en suis donc à sentir le force et le sens du vent à l'aide d'un doigt mouillé!

    "Mais repasse en Delphi Rio 10.3.3" pour profiter du debugger" va-t-on me dire.

    Il y a juste un problème, j'ai dû passer de Delphi Rio 10.3.3 à 10.4.2 (3 versions de 10.4 + 3 patchs dont un concernant le compilateur!!! Je crois être dans un cauchemar ) parce que la même app Android compilée en Delphi 10.3 plantait au démarrage sur Android 11 (mais fonctionnait sur les Android 9,10 et 12) alors que la même app, sans la moindre modification de code compilée sur Delphi 10.4.2, fonctionnait parfaitement sur tous les Android quelque soit la version!

    Tout cela me fait penser que Embarcadero, à vouloir être compatible avec tous les OS, est totalement dépassé par la tâche et se retrouve dans l'impossibilité de fournir un outil fiable!!! Ajoutons au tableau que le prix de l'abonnement annuel pour les update augmente chaque année et que la doc est remplie de "Description: Embarcadero Technologies ne possède pas d'informations supplémentaires pour le moment. Veuillez nous aider à documenter cette rubrique en utilisant la page Discussion!", cela commence à faire beaucoup!!!

    Et ce n'est pas les mails 3 fois par semaine pour me proposer d'acheter de nouvelles licences avec un rabais x ou y qui vont faire baisser ma mauvaise humeur!


    Citation Envoyé par ShaiLeTroll Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var
      lines: System.JSON.TJSONArray;
      line: System.JSON.TJSONValue;
    begin
      ...
      lines := (JsonValue as TJSONObject).GetValue('results[0].v_data.lines') as System.JSON.TJSONArray;
      for line in lines do
      begin
         ... line.GetValue('doc_line_id', 0);
     
      end;
    J'ai testé ta proposition de code et comme d'habitude quand j'essaye d'accéder au JsonArray, cela plante! Pas besoin de mettre "line.Getvalue", il suffit de faire le "for line in lines do" pour que l'erreur se déclenche.

Discussions similaires

  1. Problème de violation d'accès avec Array
    Par kracter56 dans le forum Débuter
    Réponses: 2
    Dernier message: 07/06/2012, 09h27
  2. Violation d'accès avec activeX dans IE
    Par Eric Beaumard dans le forum Web & réseau
    Réponses: 1
    Dernier message: 12/09/2008, 20h08
  3. violation d'accès avec fenetre mdi
    Par rjuju dans le forum Delphi
    Réponses: 4
    Dernier message: 15/11/2006, 14h31
  4. Réponses: 1
    Dernier message: 02/08/2006, 17h37
  5. Violation d'accès avec les composants Word 97/ 2000
    Par edechaux dans le forum Composants VCL
    Réponses: 3
    Dernier message: 07/03/2006, 09h48

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