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 :

Explication d'une instruction contenant un (des) pointeur(s) svp


Sujet :

Langage Delphi

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2022
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juillet 2022
    Messages : 22
    Points : 25
    Points
    25
    Par défaut Explication d'une instruction contenant un (des) pointeur(s) svp
    Bonjour,

    je souhaite comprendre une instruction pour savoir ce qu'elle récupère exactement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var
      RecBuf: TRecordBuffer; // où TRecordBuffer = PByte; dans Data.DB
      Data: Variant;
      Index: Integer;
    begin
    ....
    Index := ....
    Data := PVariantList(RecBuf+SizeOf(TRecInfo))[Index];
    ....
    end;
    sachant que la variable locale Index calculée peut être un entier qq > 0 et on a comme type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    type
      PVariantList = ^TVariantList;
      TVariantList = array[0..0] of Variant;
     
      PRecInfo = ^TRecInfo;
      TRecInfo = record
        RecordNumber: Integer;
        BookmarkFlag: TBookmarkFlag;
      end;
    Par avance merci

  2. #2
    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 : 55
    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 457
    Points
    28 457
    Par défaut
    le Buffer c'est je suppose une ligne d'un DataSet

    ce buffer contient un TRecInfo suivi d'un array of Variant

    donc RecBuf+SizeOf(TRecInfo) c'est une façon d'accéder en mémoire au tableau de variant qui se trouve juste après TRecInfo dans la zone mémoire pointée par RecBuf.

    PVariantList(Pointer)[Index]; c'est pour accéder au Index-ième variant du tableau

    donc en mémoire on a RecBuf = @[RecordNumber, BookmarkFlag, Variant0, Variant1, ...].

    RecBuf+SizeOf(TRecInfo)= @[Variant0, Variant1, ...].

    PVariantList(RecBuf+SizeOf(TRecInfo))[0] = [Variant0].
    PVariantList(RecBuf+SizeOf(TRecInfo))[1] = [Variant1].

    EDIT:
    la notation
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    type
      PVariantList= ^TVariantList;
      TVariantList = array[0...0] of Variant;
    c'est la notation historique où on désactive le Range Check pour accéder à un tableau dont on ne connait pas la taille

    dans une notation plus moderne on écrira simplement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    type
    {$POINTERMATH ON}
      PVariantList = ^Variant;
    avec POINTERMATH ON, un Pointeur typé réagit comme un PChar, c'est à dire que P[x] donne le xième élément du tableau alors que la déclaration indique un pointeur vers un seul élément...c'est une notation classique en C/C++ où il n'y a pas de différence entre un tableau et un pointeur sur un élément.

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2022
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juillet 2022
    Messages : 22
    Points : 25
    Points
    25
    Par défaut
    Merci Paul Toth pour cette explication super claire ! En effet la classe qui contient cet extrait de code dérive de TDataSet

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2022
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juillet 2022
    Messages : 22
    Points : 25
    Points
    25
    Par défaut
    Dans une nouvelle version du programme se déclenche une exception ERangeError sur l'instruction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Data := PVariantList(RecBuf+SizeOf(TRecInfo))[Index];
    J'ai donc voulu récupérer la taille du tableau de variant pour vérification comme ceci
    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
    type
      TArrayVar = array of Variant;
      PArrayVar = ^TArrayVar;
     
    var
      RecBuf: TRecordBuffer;
      Data: Variant;
      Index: Integer;
      tabVar: PArrayVar;
      taille: Longint;
     
    begin
    ...
      tabVar := PArrayVar(RecBuf+SizeOf(TRecInfo));
      taille := Length(tabVar^);
      Data := PVariantList(RecBuf+SizeOf(TRecInfo))[Index];
    ...
    je ne pense pas que ce mon code soit correct car taille vaut tjs 0 !

  5. #5
    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 : 55
    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 457
    Points
    28 457
    Par défaut
    j'ai donné la réponse dans ma précédente réponse où je parle juste de ce problème de Range Check

    il n'est pas possible d'obtenir la taille du tableau à partir de RecBuf puisqu'elle n'est pas renseignée.

    la taille du tableau = (DataSet.RecordSize - SizeOf(TRecInfo)) div SizeOf(Variant).

    EDIT:

    en toute logique on devrait avoir DataSet.RecordSize = SizeOf(TRecInfo) + DataSet.FieldCount * SizeOf(Variant) avec un variant par champ

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

Discussions similaires

  1. Ajout d'une colonne contenant que des 1
    Par lileric dans le forum MATLAB
    Réponses: 1
    Dernier message: 06/05/2011, 18h09
  2. Réponses: 19
    Dernier message: 14/08/2007, 15h41
  3. Explication d'une instruction de test
    Par ToTo13 dans le forum C
    Réponses: 8
    Dernier message: 07/02/2007, 18h02
  4. Réponses: 11
    Dernier message: 08/12/2006, 22h39
  5. Explication sur une instruction...
    Par snoop dans le forum C++
    Réponses: 5
    Dernier message: 03/05/2006, 23h56

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