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

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

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2017
    Messages : 1 778
    Points : 5 714
    Points
    5 714
    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 679
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 679
    Points : 13 084
    Points
    13 084
    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
    1 778
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2017
    Messages : 1 778
    Points : 5 714
    Points
    5 714
    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 sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    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 447
    Points : 24 846
    Points
    24 846
    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 sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    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 447
    Points : 24 846
    Points
    24 846
    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
    1 778
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2017
    Messages : 1 778
    Points : 5 714
    Points
    5 714
    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.

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

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2017
    Messages : 1 778
    Points : 5 714
    Points
    5 714
    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).

  8. #8
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    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 447
    Points : 24 846
    Points
    24 846
    Par défaut
    0000008C c'est proche de zéro, cela n'ai rien de bon, comme si cela pointait sur une adresse nil + offset
    Android c'est du 32bits ???

    Faudrait balayer les noeuds manuellement sans passer par un chemin (en XMLDocument, je me souviens d'un problème de compteur de référence, si l'on ne lui fournissait pas de Owner ou que l'on passait par des interfaces, les références d'objet avaient une mort prématurée)

    En tout cas, ne surtout pas libérer JsonValue
    Qui est surement le propriétaire de la collection d'objet


    Le code fonctionne-t-il sous Windows ?
    Android, je ne connais pas, FMX non plus, je fais que du développement Serveur, mes clients étant le middleware PHP ... donc à l'opposé de la chaine logicielle.

    le JSON est-il gros ?
    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

  9. #9
    Membre expert
    Avatar de pprem
    Homme Profil pro
    MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Inscrit en
    Juin 2013
    Messages
    1 876
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 876
    Points : 3 611
    Points
    3 611
    Par défaut
    Bonjour

    Avant d'incriminer Embarcadero pour tout un tas de choses qui sont aussi beaucoup liées aux éditeurs des systèmes d'exploitation et appareils mobiles, pourrais-tu vérifier que ce que tu récupères est valide ? genre que ça n'est pas à "nil", ce qui expliquerait l'erreur

    Utiliser le chemin pour récupérer des trucs dans le JSON, je n'avais jamais tenté (probablement parce que je ne manipule que très rarement de XML), bon à savoir que ça passe comme dans REST Debugger. Par contre est-ce que tu peux récupérer le noeud qui contient Lines, puis faire un GetValue<TJSONArry> dessus ou est-ce que ça plante aussi ?

    Ce qui est étonnant c'est que le ShowMessage() te fournisse la bonne classe, ça laisse supposer qu'il le repère et n'est donc pas nil. Le tableau a-t-il des éléments ? (tente un for i := 0 to lines.count-1 au lieu du for in)

    Et effectivement, est-ce que ton code fonctionne sous Windows ?

    Même si des fois le debugger est inutilisable sur Android (me souviens pas de big problèmes en 10.4.2 mais c'est possible), ce que tu programmes dois fonctionner à l'identique aussi sous Windows, donc vérifie dessus.

    Le JSON global semble être un tableau avec un seul élément, c'est un peu bizarre comme choix. Tu fais appel à une API sur laquelle tu as la main ou c'est imposé par un tiers ? Peux-il y avoir plusieurs éléments à la reine de la réponse ?

    Comme dit plus haut, les manipulations d'un arbre JSON avec System.JSON ne retourne que des pointeurs vers l'objet de départ. Aucun Free ne doit être fait sur les variables qui sont alimentées dessus sinon ça pête. Seule libération à faire sur la zone globale une fois qu'on a terminé de la manipuler.

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

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2017
    Messages : 1 778
    Points : 5 714
    Points
    5 714
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    0000008C c'est proche de zéro, cela n'ai rien de bon, comme si cela pointait sur une adresse nil + offset
    Android c'est du 32bits ???
    Oui, la cible est Android 32 bits

    Citation Envoyé par ShaiLeTroll Voir le message
    Le code fonctionne-t-il sous Windows ?
    Android, je ne connais pas, FMX non plus, je fais que du développement Serveur, mes clients étant le middleware PHP ... donc à l'opposé de la chaine logicielle.
    Le code ne risque pas de fonctionner sous Windows (j'ai déjà testé), il s'agit d'une app complexe faisant appel à des techno spécifiques à Android. Concernant le code manipulant le JSON, il correspond au code présenté en exemple sur toutes les sources (doc Embarcadero ou forum de discussion). Dès lors, j'ai l'impression qu'il y a un effet de bord lié à un élément spécifique de l'app en question. Reste à savoir lequel.

    Citation Envoyé par ShaiLeTroll Voir le message
    le JSON est-il gros ?
    Non. Un JSON avec 3 noeuds principaux dont un Array d'une centaine de ligne max.

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

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2017
    Messages : 1 778
    Points : 5 714
    Points
    5 714
    Par défaut
    Citation Envoyé par pprem Voir le message
    Bonjour

    Avant d'incriminer Embarcadero pour tout un tas de choses qui sont aussi beaucoup liées aux éditeurs des systèmes d'exploitation et appareils mobiles, pourrais-tu vérifier que ce que tu récupères est valide ? genre que ça n'est pas à "nil", ce qui expliquerait l'erreur
    Vu ta position, je comprends parfaitement que tu prennes la défense de Embarcadero. Seulement tout ce que je cite est une réalité et ne dépend pas de sociétés tierces:

    1. Quand on sort une version (Delphi 10.4 en l’occurrence) et qu'il faut 3 versions successives et 3 patchs pour rendre la version "utilisable", tu ne peux pas venir dire que le produit est fiable. Toi, tu diras "C'est super. Cela prouve que Embarcadero est réactif". Moi, je vais te dire que Delphi 10.4 a été publié alors que le produit n'était pas fiabilisé. Si commercialement, il ne fallait pas sortir à tout prix le Delphi 11, on en serait au 30ème patchs de Delphi 10.4!!!

    Tu ne dois certainement pas payer souvent une facture à Embarcadero, mais ma société oui! Comme Embarcadero veut faire passer à la caisse chaque année le client à l'obligeant à payer un abonnement annuel représentant 25% du prix d'achat d'une licence, il faut absolument sortir une nouvelle version tous les 6 mois pour que le client n'ait pas l'impression d'être volé. Et Embarcadero sort une version même si son équipe technique sait que la version n'est pas en état de l'être. Inutile de se le cacher, ce défaut est présent dans le 100% des entreprises du monde où la vente veut vendre sans se soucier d'autre chose.

    Le problème de cette approche est que le client finit par se poser la question si les défauts sont dus à la sortie trop rapide d'une version ou si les défauts sont expressément laissés pour que le client se sente obligé de payer chaque année la dime!


    2. Je suis un vieux utilisateur de Delphi (depuis Delphi7) et mon expérience confirme que plus on avance, plus je suis confronté à des bugs de Delphi: Que cela soit au niveau de l'IDE lui-même avec des problèmes d'interface, des problèmes au niveau des composants ou pire encore au niveau de la compilation.

    3. Est-ce que tu as l'habitude d'acheter une voiture, un téléviseur ou un médicament avec un mode d'emploi remplit de "On sait pas quoi vous dire pour expliquer cette fonction. Mais n'hésitez pas à nous donner des info pour que l'on puisse compléter notre mode d'emploi"? Perso, je connais une seule entreprise qui le fait... Embarcadero!

    Est-ce que cela donne l'impression que Embarcadero domine son sujet? Je ne crois pas! D'autant plus quand cela concerne des composants qui sont présents dans Delphi depuis de nombreuses années!

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

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2017
    Messages : 1 778
    Points : 5 714
    Points
    5 714
    Par défaut
    Citation Envoyé par pprem Voir le message
    Le tableau a-t-il des éléments ? (tente un for i := 0 to lines.count-1 au lieu du for in)
    Faire un...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     for i:=0 to lines.count-1 do
     begin
      //...
     end;
    se termine par un "violation error"!

    Le plus drôle est que si je fais...

    Cela ne plante pas, mais si je fais...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    i:=lines.count;
     
      try
       Memo1.lines.add('i= '+IntToStr(i));
      except
       Memo1.lines.add('IntToStr(i) en exception');
      end;
    Cela plante avec un "violation error" et que l'erreur ne déclenche même pas l'except...

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

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2017
    Messages : 1 778
    Points : 5 714
    Points
    5 714
    Par défaut
    Citation Envoyé par pprem Voir le message

    Le JSON global semble être un tableau avec un seul élément, c'est un peu bizarre comme choix. Tu fais appel à une API sur laquelle tu as la main ou c'est imposé par un tiers ? Peux-il y avoir plusieurs éléments à la reine de la réponse ?
    Fine observation! C'est non seulement un tableau avec un seul élément, c'est un tableau sans nom!

    En réalité, c'est un bug d'une API dont je n'ai pas le contrôle. Au lieu de retourner un JSON selon le format {...}, il retourne un [{..}].

    Pour pouvoir utiliser la réponse, je dois au préalable modifier le JSON reçu: Je récupère le JSON en texte et fais une modification, soit virer les [] de début et de fin, soit mettre un nom au tableau d'origine par ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    JSONresponse_str:=RESTResponse1.JSONText;
    JSONresponse_str:='{"results":'+RESTResponse1.JSONText+'}';
    et ensuite je récupère la réponse modifiée comme JSON:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    JsonValue := TJSonObject.ParseJSONValue(JSONresponse_str);
    A noter que je peux accéder aux lignes du tableau 'lines par un JsonValue<string> sans que cela plante comme dans le code ci-dessous

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    str:=JsonValue.GetValue<string>('results[0].v_data.header.doc_id');
                                Memo1.lines.add('doc_id: '+str);
     
    str:=JsonValue.GetValue<string>('results[0].v_data.lines[0].doc_line_id');
                                Memo1.lines.add('doc_line_id: '+str);
    Je me suis déjà posé la question, si cette manipulation pouvait être à l'origine de l'access violation ultérieur...

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 679
    Points : 13 084
    Points
    13 084
    Par défaut
    Citation Envoyé par Anselme45 Voir le message
    Le plus drôle est que si je fais i:=lines.count; Cela ne plante pas, mais si je fais...
    C'est l'optimisation du code, i n'étant pas utilisé ultérieurement la ligne n'est pas compilée.

    Est-ce que tu peux fournir un extrait de la réponse json avant bidouille ?

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

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2017
    Messages : 1 778
    Points : 5 714
    Points
    5 714
    Par défaut
    Citation Envoyé par pprem Voir le message
    Par contre est-ce que tu peux récupérer le noeud qui contient Lines, puis faire un GetValue<TJSONArry> dessus ou est-ce que ça plante aussi ?
    Incroyable avec GetValue<TJSONArray>, cela semble fonctionner.

    Avec le code suivant, je peux afficher dans mon memo de test, le contenu du JSONArray sous forme de string et plus fort encore (il y a des jours où l'on se contente de peu), j'arrive à obtenir et à afficher le nombre de lignes du TJSONArray.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    JSONValue:= TJSONObject.ParseJSONValue(JSONresponse_str);
     
    myJSONArray:=JSONValue.GetValue<TJSONArray>('results[0].v_data.lines');
       Memo1.lines.add('myJSONArray= '+myJSONArray.ToString); //DEBUG
     
       int22:=myJSONArray.Count;  //DEBUG
     
       Memo1.lines.add('myJSONArray.count= '+inttostr(int22)); //DEBUG
    Je ne comprends toujours pas pourquoi il y avait des "access violation error" et pourquoi l'erreur a disparu maintenant. Je vais poursuivre mes tests avant de noter la discussion comme résolue.

    Le JSON récupéré de l'API et modifié par mes soins était donc OK. Il semble que le problème ait pour origine la méthode de récupération du tableau 'lines' dans une variable JSONArray. Avec un "GetValue<TJSONArray>", cela fonctionne mais pas avec les autres codes proposés habituellement..


    Je tiens encore à remercier tous les intervenants qui m'ont aidé et plus particulièrement pprem qui a eu l'idée du GetValue<TJSONArray>

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 679
    Points : 13 084
    Points
    13 084
    Par défaut
    Citation Envoyé par Anselme45 Voir le message
    Je tiens encore à remercier tous les intervenants qui m'ont aidé et plus particulièrement pprem qui a eu l'idée du GetValue<TJSONArray>
    Pourtant c'était ma première proposition que tu semblais déjà avoir testé

    Quelque chose a quant même été changé entretemps...

  17. #17
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    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 447
    Points : 24 846
    Points
    24 846
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Faudrait balayer les noeuds manuellement sans passer par un chemin
    Citation Envoyé par Andnotor Voir le message
    tu récupères nœud après nœud (results puis v_data puis enfin lines)


    Oui semble que personne ne lit les propositions, c'est aussi ce que l'on propose depuis le début

    on devine que le chemin récupère la valeur finale mais libère les objets intermédiaires, cela foncitonne une pour GetValue<string> qui retourne une copie de la valeur mais pas pour GetValue<TObject> où cela libère l'arbre propriétaire
    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

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

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2017
    Messages : 1 778
    Points : 5 714
    Points
    5 714
    Par défaut
    Citation Envoyé par Andnotor Voir le message
    Pourtant c'était ma première proposition que tu semblais déjà avoir testé

    Quelque chose a quant même été changé entretemps...
    Oui, il y a quelque chose qui a changé!!!

    Mes tests infructueux étaient compilés sur Delphi 10.4.2.

    Je suis repassé à Delphi 10.3.3 et cela semble fonctionner.

    D'où mon commentaire "je dois continuer mes tests avant de considérer la discussion comme résolue" pour la bonne et simple raison que je ne vais pas pouvoir rester en Delphi 10.3.3 parce que mon app Android compilée sur Delphi 10.3.3 plante au démarrage sur les appareils Android 11 mais fonctionne avec tous les autres versions Android y compris Android 12!

    Est-ce qu'au final, c'est Delphi 11 version x patch y qui va mettre tout le monde d'accord?

    Et que cela se sache, je lis "religieusement" tous vos commentaires... Il serait parfaitement idiot, inconvenant et irrespectueux de ne pas le faire!

    Merci encore à tous pour vos contributions

  19. #19
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 029
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 029
    Points : 40 927
    Points
    40 927
    Billets dans le blog
    62
    Par défaut
    Bonjour,

    Perso, je n'ai jamais utilisé la 10.4 en "production" justement à cause de problèmes avec REST et JSON.
    Cependant, même en 10.3 je reste toujours bloqué quand j'obtiens une réponse du serveur (200) mais aucune données

    mon application Android compilée sur Delphi 10.3.3 plante au démarrage sur les appareils Android 11
    Tellement de permissions ont été ajoutées avec Android 11 qu'il s'agit peut-être d'un besoin non abouti et peut-être qu'Android 12 gère mieux ce souci
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  20. #20
    Membre expert
    Avatar de pprem
    Homme Profil pro
    MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Inscrit en
    Juin 2013
    Messages
    1 876
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 876
    Points : 3 611
    Points
    3 611
    Par défaut
    Bon, au moins un début de solution pour te débloquer, c'est déjà ça.

    ** Hors sujet **

    Concernant les remarques sur Embarcadero, même si je n'ai plus à payer les licences car incluses dans le cadre du contrat de partenariat MVP (lisible sur leur site si ça vous intéresse), je n'en reste pas moins critique sur un certain nombre de choses, même si je ne l'écris pas forcément ici et me contente de ronchonner en live ailleurs ou en interne directement.

    Suis d'accord avec toi quand tu dis que certaines versions n'auraient pas dû sortir quand elles sont sorties. On en est tous conscients. Le problème c'est qu'il y a toujours des trucs qu'on ne voit pas sur les beta tests et qui ne se produisent qu'en situation réelle. Ne pas hésiter à demander à faire partie des beta tests pour valider vos logiciels quand l'accès est ouvert à une sélection de clients.

    iOS et Android imposent des changements réguliers. Embarcadero suit sous forme de patchs ou d'updates selon ce qui est possible de faire ou pas avec les contraintes qui sont les leurs (et que Microsoft n'a pas avec VSCode, puisque c'est la comparaison habituelle pour le système de mises à jour). Et puisque je parle de mises à jours, la prochaine version serait une 11.3 (update de la 11.x) en attendant la 12.0 Certaines infos ont été dévoilées lors de la conférence brésilienne en novembre. Je vous laisse chercher un peu.

    Pour la doc suis tout à fait d'accord et fais régulièrement des remontées pour demander des infos sur des trucs documentés mais non documentés. D'ailleurs n'hésitez pas à le faire aussi si vous tombez sur des pages pour lesquelles "Embarcadero ne sait rien". Ca prend 5 minutes, mais au moins derrière ils voient sur quoi ajouter des infos et les traitent au fil des versions. En bas de la doc Windows il y a un lien "voir en ligne" ou équivalent qui amène sur le docwiki où vous avez un lien "qp" en pied de chaque page. N'hésitez surtout pas à les utiliser.

    ** Fin du hors sujet **

    Pour l'API retournant un tableau avec un seul élément qui est un objet, tu peux ne pas t'embêter à le retransformer en objet.

    Dans les versions antérieures à la 11.0 on n'avait le ParseJSONValue() uniquement au niveau de TJSONObject, mais en fait il peut aussi sortir un tableau. Donc un tabJS:=TJSONObject.ParseJSONValue(TaChainsJSON) as TJSONArray te permettrait d'avoir un tabJS[0] pointant directement sur l'objet qui t'intéresse et pouvoir le manipuler sans t'embêter avec "result[0]" partout. Par contre c'est ce tabJS qu'il faudra libérer une fois la fin de tes manipulations.

    Depuis la 11.0 ParseJSONValue() a été redescendu au niveau du TJSONValue et est disponible partout, mais retourne toujours un TJSONValue que nous devons transtyper dans le type attendu. C'est l'un des nombreux tickets provenants de développeurs qui a été pris en compte dans cette version (oui, ça sert de faire des demandes d'améliorations en nouvelles fonctionnalités, même si ça peut prendre du temps).

    Concernant ton code, si ça fonctionne en 10.3.x et pas en 10.4.x il y a un bogue qui ne devrait pas y être. J'peux vérifier sur la 11 si tu ne peux pas le faire de ton côté (mais me faudra un bout de JSON à tester et une partie de ton code).
    Si l'accès au tableau final passe à la main mais pas avec le chemin complet alors que d'autres chemins passent, c'est aussi un bogue. Même chose, j'peux tester et faire la remontée si tu ne peux pas le faire de ton côté.

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