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

Lazarus Pascal Discussion :

Données différentes entre array statique et array dynamique [Lazarus]


Sujet :

Lazarus Pascal

  1. #1
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 699
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 699
    Points : 15 042
    Points
    15 042
    Par défaut Données différentes entre array statique et array dynamique
    Bonjour,

    Soit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    type
      TByteArray = array of byte;
     
    procedure TForm1.btnTestWriterClick(Sender: TObject);
    var
      Sbuffer: array[0..44099] of byte; // ancien, ok
      Dbuffer: TByteArray; // nouveau, kc
    Ensuite,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    begin
      asize := SizeOf(Sbuffer);
      showmessage(inttostr(asize)); //44100, ok
      asr := 44100;
      SetLength(Dbuffer, asr);
      showmessage(inttostr(length(Dbuffer))); //44100, ok
    //jusque là on est bon, alors on continue :
      for i := 0 to asr-1 do Sbuffer[i] := 0; // init buffer
      for i := 0 to asr-1 do Dbuffer[i] := 0; // init buffer
    puis j'initialise des variables, puis je remplis les buffers :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      for i := 0 to asr-1 do begin
        SineCount := SineCount + (Frequency / asr);
        Sbuffer[i] := Round(Sin(SineCount * 2 * PI) * Amplitude*127);
        Dbuffer[i] := Sbuffer[i];
      end;
    Je les enregistre (c'est la même fonction d'écriture, utilisée par l'un puis par l'autre buffer), je les ouvre avec un éditeur hexa et... les données ne sont pas les mêmes ! Au début, 3 blocs de 4 bytes en plus (sortis d'où ?) dans Dbuffer (le dynamique). Après ça s'arrange. Et à la fin il lui manque 3 blocs de 4 bytes, évidemment...
    Je vous mets une 'tite image du début des deux fichiers, avec le pas bon en haut et en rouge transparent ce qui est en trop :
    Nom : compar_da-db-v2.png
Affichages : 215
Taille : 74,1 Ko

    Si quelqu'un a une idée...

    PS : merci pour tes vœux, Gilles, les miens en retour.

    EDIT : une précision, qui a peut-être son importance, j'ai rajouté un petit test :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        ...
        Dbuffer[i] := Sbuffer[i];
        if i < 50 then
          memo.Lines.Add(inttostr(i)+'  S: '+inttostr(Sbuffer[i])+'  D: '+inttostr(Dbuffer[i]));
    pour voir ce qui se passe et bien sûr, le log montre que les données sont identiques.
    C'est donc la fonction SaveToWav (qui vient ensuite), qui met sa pagaille ?

    Mais comment ?
    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
    function SaveToWav(const aFilename:String; var LeBuffer;
      aBufferSize, aBitsPerSample, aSampleRate, aChannelCount :Integer): Boolean;
    var
      wTmp :TWavWriter;
    begin
      Result := False;
      wTmp := TWavWriter.Create;
      with wTmp do
        try
          StoreToFile(aFilename); // création du fichier récepteur
          // création des données
          fmt.BitsPerSample := aBitsPerSample;
          fmt.SampleRate    := aSampleRate;
          fmt.Channels      := aChannelCount;
              // 2 lignes missing :
          fmt.BlockAlign    := aChannelCount * aBitsPerSample div 8;
          fmt.ByteRate      := fmt.BlockAlign * aSampleRate;
          WriteBuf(LeBuffer, aBufferSize);
          Result := true;
        finally
          Free;
        end;
    end;
    Vous voulez voir WriteBuf ? Yakà demander :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function TWavWriter.WriteBuf(var Buffer; BufferSize: Integer): Integer;
    var
      sz: Integer;
    begin
      Result := 0;
      with fStream do begin
        sz := Write(Buffer, BufferSize);
        if sz < 0 then Exit;
        Inc(Result, sz);
      end;
    end;
    Pas de quoi fouetter un chat, et c'est un peu pareil avec StoreToFile, qui commence par créer un TFileStream, qui sera rempli par un StoreToStream :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function TWavWriter.StoreToStream(AStream:TStream):Boolean;
    begin
      fStream := AStream;
      FFreeStreamOnClose := False;
      with fmt, ChunkHeader do begin
        ID := AUDIO_CHUNK_ID_fmt;
        Size := SizeOf(fmt) - SizeOf(ChunkHeader);
        Format := AUDIO_FORMAT_PCM;
      end;
      Result := FlushHeader;
    end;
    Il ne reste plus que FlushHeader comme coupable potentiel mais alors, la grande question se pose : pourquoi juste 12 bytes en plus au début du datachunk quand on appelle la fonction pour la seconde fois ?
    Étant entendu que j'ai attaqué ce post avec les deux arrays ensemble pour montrer les articulations, après m'être rendu compte que travailler avec uniquement la dynamique posait un problème...
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  2. #2
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 409
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 409
    Points : 5 799
    Points
    5 799
    Par défaut
    salut
    essai la fonction length
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SetLength(Dbuffer, asr);
    le compteur commence a zero

    pour la boucle j'utilise
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Low(Sbuffer) to High(Sbuffer)
    apres il manque des elements pour comprendre vraiment cette difference
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  3. #3
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 699
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 699
    Points : 15 042
    Points
    15 042
    Par défaut
    Yep !

    Citation Envoyé par anapurna Voir le message
    salut
    essaie la fonction length
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    asr := Length(Sbuffer);
    Pour quoi faire ? Il n'y a pas de problème avec l'array Statique.
    Cette variable asr est bien définie, une valeur lui est assignée avant et elle est utilisée dans l'autre sens, , pour définir la taille du Dbuffer

    Citation Envoyé par anapurna Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SetLength(Dbuffer, asr);
    le compteur commence à zéro
    Yes yes, ça a été testé.

    Citation Envoyé par anapurna Voir le message
    pour la boucle j'utilise
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Low(Sbuffer) to High(Sbuffer)
    Pas de problème avec l'array Statique.

    Citation Envoyé par anapurna Voir le message
    après il manque des éléments pour comprendre vraiment cette différence
    À quoi penses-tu ?

    Moi, là où j'ai peur, c'est que j'ai l'impression que le problème se situerait plus du côté de la cuisine FPC car tous les tests montrent que tout va bien jusqu'à ce que j'appelle la fonction d'écriture proprement dite de pfwavwriter.
    (ce qui n'explique pas le problème avec l'array Dynamique, inexistant avec l'array Statique,

    Et mettre les mains là-dedans, je n'y suis pas arrivé : quand j'y insère des write(ln), ça ne m'affiche pas les lignes que j'attends...
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  4. #4
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 844
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 844
    Points : 11 274
    Points
    11 274
    Billets dans le blog
    6
    Par défaut
    Bonjour Jean-Pierre,

    Il me semble qu'un tableau dynamique est un pointeur sur une zone mémoire qui comprend le nombre d'éléments, un compteur de référence et les éléments alors qu'un tableau statique ne comprend que ses éléments.

    Je pense que le non-typage du paramètre buffer que tu passes et repasses pose problème, même si je ne comprends pas pourquoi il y a précisément 12 octets de décalage

    Passer l'adresse du 1er élément du tableau, statique ou dynamique, devrait unifier le comportement.

    Meilleurs vœux,
    Yves.
    Delphi 5 Pro - Delphi 10.4 Rio Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  5. #5
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 699
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 699
    Points : 15 042
    Points
    15 042
    Par défaut
    Citation Envoyé par tourlourou Voir le message
    Il me semble qu'un tableau dynamique est un pointeur sur une zone mémoire qui comprend le nombre d'éléments, un compteur de référence et les éléments alors qu'un tableau statique ne comprend que ses éléments.
    Pourquoi n'y a-t'il pas un mot de ça dans l'aide ?

    J'ai quand même tenté de remplacer ma TByteArray par une bête Array of Byte mais ça ne change rien au comportement erroné...
    Citation Envoyé par tourlourou Voir le message
    Passer l'adresse du 1er élément du tableau, statique ou dynamique, devrait unifier le comportement.

    Meilleurs vœux,
    Yves.
    Les miens en retour et, peux-tu préciser la manip ? (les pointeurs n'ont jamais été ma tasse de thé...)
    Merci,
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  6. #6
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 844
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 844
    Points : 11 274
    Points
    11 274
    Billets dans le blog
    6
    Par défaut
    Je verrais un appel sur ce modèle (à la syntaxe précise près) : if SaveToWav( MyFilename, @MyTab[0], Length(MyTab), MyBitsPerSample, MySampleRate, MyChannelCount) then
    Delphi 5 Pro - Delphi 10.4 Rio Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  7. #7
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 699
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 699
    Points : 15 042
    Points
    15 042
    Par défaut
    Citation Envoyé par tourlourou Voir le message
    Je verrais un appel sur ce modèle (à la syntaxe précise près) : if SaveToWav( MyFilename, @MyTab[0], Length(MyTab), MyBitsPerSample, MySampleRate, MyChannelCount) then
    @MyTab[0] --> Unit1.pas(712,47) Error: Can't assign values to an address

    MyTab[0] --> BINGO ! Un truc de malade, de guedin, qui pourrait bien penser à ça, mmmh ?




    Allez hop !, , l'année commence bien !
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 671
    Points : 13 065
    Points
    13 065
    Par défaut
    Citation Envoyé par tourlourou Voir le message
    même si je ne comprends pas pourquoi il y a précisément 12 octets de décalage
    C'est manifestement du 64 bits : la longueur est codée sur 8 octets (4 en 32) et le compteur de référence sur 4 octets.

    Citation Envoyé par Jipété Voir le message
    Pourquoi n'y a-t'il pas un mot de ça dans l'aide ?
    Dynamic array types

  9. #9
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 699
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 699
    Points : 15 042
    Points
    15 042
    Par défaut
    Citation Envoyé par Andnotor Voir le message
    Bonsoir et merci pour ces précisions, il n'en reste pas moins vrai qu'il n'y a pas un mot sur le fait qu'il faut accéder comme je l'ai indiqué (arrayname[0]) pour que ça fonctionne avec une array dynamique, ni dans ton lien ni dans l'aide de la distrib' officielle.

    Je n'ai pas fait de tests pour savoir s'il était possible d'obtenir directement le 16e byte en passant ...[15], l'expérience le dira.

    Le truc qui est curieux, toujours dans l'aide officielle, c'est l'accès aux données d'un tableau statique, qui commence à 1 ! :
    Citation Envoyé par aide Lazarus
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Type  
      RealArray = Array [1..100] of Real; 
    ...
    Type  
       APoints = array[1..100] of Array[1..3] of Real;
    Faut bien se graver ça au fer rouge à l'intérieur de la tête,
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  10. #10
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 844
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 844
    Points : 11 274
    Points
    11 274
    Billets dans le blog
    6
    Par défaut
    Je ne parviens (en 32 bits) pas à trouver la taille avec le code suivant :
    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
    procedure TForm1.Button1Click(Sender: TObject);
    var
      aTab1, aTab2: array of Byte;
      i: integer;
    begin
      Memo1.Lines.Add(Cardinal(aTab1).ToHexString(8));
      SetLength(aTab1, 8);
      for i := 0 to 7 do aTab1[i] := i;
      aTab2 := aTab1; // est-ce que ça suffit à incrémenter le compteur de référence ? et du tab 1 ou 2 ?
       // contenu, en positif
      Memo1.Lines.Add(PQWord(Cardinal(aTab1))^.ToHexString(16));
      // datas en négatif
      Memo1.Lines.Add(PCardinal(Cardinal(aTab1)-2)^.ToHexString(8));
      Memo1.Lines.Add(PWord(Cardinal(aTab1)-1)^.ToString);
      Memo1.Lines.Add(PCardinal(Cardinal(aTab1)-1)^.ToHexString(8));
      Memo1.Lines.Add(PWord(Cardinal(aTab1)-2)^.ToString);
      //
      Memo1.Lines.Add('--');
      Memo1.Lines.Add(Cardinal(aTab1).ToHexString(8));
      Memo1.Lines.Add(Cardinal(@aTab1[0]).ToHexString(8));
    end;
    qui fournit :
    00000000 // Un tableau vide est nil
    0706050403020100 // éléments du tableau
    01000000 // ce n'est pas le nombre d'éléments
    0 // RC ?
    02010000 // ici non plus !
    0 // // RC ?
    --
    02AF6038
    02AF6038
    [EDIT] en cherchant les 2 Cardinal aux offsets négatifs (je suis en 32 Bits), j'obtiens 02010000 et 01000000. Si 1 pourrait être la valeur du compteur de référence (?), je ne vois pas l'autre comme la taille (8) !
    Delphi 5 Pro - Delphi 10.4 Rio Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 671
    Points : 13 065
    Points
    13 065
    Par défaut
    Citation Envoyé par Jipété Voir le message
    il n'en reste pas moins vrai qu'il n'y a pas un mot sur le fait qu'il faut accéder comme je l'ai indiqué (arrayname[0])
    Parce que ça va dépendre de la fonction elle-même. Par définition un paramètre non typé est de type inconnu, c'est dans le code de la fonction qu'il y aura transtypage dans le type attendu. Ici elle attend manifestement une valeur et non une référence.

    Citation Envoyé par Jipété Voir le message
    Le truc qui est curieux, toujours dans l'aide officielle, c'est l'accès aux données d'un tableau statique, qui commence à 1 !
    Rien de choquant, un tableau statique peut commencer à n'importe quel indice (y compris négatif) et c'est pour ça que la fonction Low() existe.

    Citation Envoyé par tourlourou Voir le message
    Je ne parviens (en 32 bits) pas à trouver la taille avec le code suivant
    Parce que tes offsets ne sont pas corrects. Ce n'est pas -1 mais -SizeOf(integer)

    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
    procedure TForm1.Button1Click(Sender: TObject);
    type
      PHeader = ^THeader;
      THeader = packed record
        RefCount :integer;
        Length   :integer;
      end;
     
    var
      aTab1, aTab2 :array of byte;
      Header :PHeader;
     
    begin
      SetLength(aTab1, 10);
     
      Header := PHeader(cardinal(aTab1) -SizeOf(THeader));
      Memo1.Lines.Add(Format('RefCount : %d, Length : %d', [Header^.RefCount, Header^.Length]));
     
      aTab2 := aTab1;
      Memo1.Lines.Add(Format('RefCount : %d, Length : %d', [Header^.RefCount, Header^.Length]));
    end;

  12. #12
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 844
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 844
    Points : 11 274
    Points
    11 274
    Billets dans le blog
    6
    Par défaut
    Arf, merci Andnotor ! Je calculais l'offset en arithmétique des pointeurs mais avait mal positionné les parenthèses...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Memo1.Lines.Add( ( PCardinal(Cardinal(aTab1)) - 2 )^.ToHexString(8));
    Delphi 5 Pro - Delphi 10.4 Rio Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  13. #13
    Membre actif
    Homme Profil pro
    libre
    Inscrit en
    Juin 2019
    Messages
    205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : libre

    Informations forums :
    Inscription : Juin 2019
    Messages : 205
    Points : 292
    Points
    292
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     WriteBuf(var Buffer; BufferSize: Integer)
     SaveToWav(const aFilename:String; var LeBuffer;
    Les paramètres Buffer, LeBuffer doivent être marqués comme étant const non typé en lecture.

    Bonsoir et merci pour ces précisions, il n'en reste pas moins vrai qu'il n'y a pas un mot sur le fait qu'il faut accéder comme je l'ai indiqué (arrayname[0]) pour que ça fonctionne avec une array dynamique
    C'est du bricolage mais fonctionne pour les deux types.

    pour les tableaux statiques il faut passer directement le variable comme la fonction Move

    WriteBuf(tab, ...

    pour les tableaux dynamiques

    WriteBuf(Pointer(tab)^, ...

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 671
    Points : 13 065
    Points
    13 065
    Par défaut
    Citation Envoyé par tourlourou Voir le message
    Arf, merci Andnotor ! Je calculais l'offset en arithmétique des pointeurs mais avait mal positionné les parenthèses...
    A moins qu'il y ait une nouvelle fois une différence FP/Delphi, ta modif ne devrait pas compiler puisque tu tentes de décrémenter le pointeur et non l'entier

    Et ton offset est toujours faux (2), tu lis les deux octets de poids fort de la longueur et les deux premiers éléments du tableau de bytes, d'où le 01000000 de tes premiers tests.

  15. #15
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 699
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 699
    Points : 15 042
    Points
    15 042
    Par défaut
    Bonsoir,

    Citation Envoyé par wheel Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     WriteBuf(var Buffer; BufferSize: Integer)
     SaveToWav(const aFilename:String; var LeBuffer;
    Les paramètres Buffer, LeBuffer doivent être marqués comme étant const non typé en lecture.
    Merci pour ces précisions, j'en prends bonne note et vais les mettre en œuvre.

    Citation Envoyé par wheel Voir le message
    C'est du bricolage mais fonctionne pour les deux types.

    pour les tableaux statiques il faut passer directement le variable comme la fonction Move

    WriteBuf(tab, ...

    pour les tableaux dynamiques

    WriteBuf(Pointer(tab)^, ...
    C'est du bricolage parce qu'il faut qu'on s'adapte à un machin qui est déjà du bricolage !
    Je trouve dément et scandaleux que lors d'une compilation avec un tableau dynamique, rien ne nous dise qu'on n'utilise pas la bonne syntaxe (sans compter le fait qu'il n'y a rien dans l'aide là-dessus)...

    Merci pour tout ça.
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  16. #16
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 844
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 844
    Points : 11 274
    Points
    11 274
    Billets dans le blog
    6
    Par défaut
    Citation Envoyé par Andnotor Voir le message
    A moins qu'il y ait une nouvelle fois une différence FP/Delphi, ta modif ne devrait pas compiler puisque tu tentes de décrémenter le pointeur et non l'entier

    Et ton offset est toujours faux (2), tu lis les deux octets de poids fort de la longueur et les deux premiers éléments du tableau de bytes, d'où le 01000000 de tes premiers tests.
    Il y en a donc une !
    Avec ce code :
    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
    procedure TForm1.Button1Click(Sender: TObject);
    var
      aTab1, aTab2: array of Byte;
      i, aSize: integer;
    begin
      Memo1.Lines.Add(Cardinal(aTab1).ToHexString(8));
      aSize := 20;
      SetLength(aTab1, aSize);
      for i := 0 to aSize-1 do aTab1[i] := aSize-i;
     
      // aTab2 := aTab1; // ça suffit à incrémenter le compteur de référence de 1 à 2 
     
       // contenu, en positif
      Memo1.Lines.Add(PQWord(Cardinal(aTab1))^.ToHexString(16));
      // datas en négatif
      Memo1.Lines.Add((PCardinal(Cardinal(aTab1))-1)^.ToHexString(8));
      Memo1.Lines.Add((PCardinal(Cardinal(aTab1))-2)^.ToHexString(8));
     
      //
      Memo1.Lines.Add('--');
      Memo1.Lines.Add(Cardinal(aTab1).ToHexString(8));
      Memo1.Lines.Add(Cardinal(@aTab1[0]).ToHexString(8));
    end;
    j'obtiens :
    00000000
    0D0E0F1011121314
    00000013
    00000001
    --
    00126CF8
    00126CF8
    Ce qui valide sous CodeTyphon les offsets négatifs et l'arithmétique des pointeurs (un pointeur typé est décrémenté/incrémenté de la longueur du type qu'il pointe) mais pas l'aide de FPC puisque ce n'est pas la taille du tableau qui est stockée, mais son indice le plus haut !
    Delphi 5 Pro - Delphi 10.4 Rio Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  17. #17
    Membre actif
    Homme Profil pro
    libre
    Inscrit en
    Juin 2019
    Messages
    205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : libre

    Informations forums :
    Inscription : Juin 2019
    Messages : 205
    Points : 292
    Points
    292
    Par défaut
    j'en prends bonne note et vais les mettre en œuvre.
    En pratique ça ne change rien les deux écritures vont passer la même adresse et rien n'oblige de suivre cette règle mais afin que les autres programmeurs Pascal/Delphi comprennent votre code vaut mieux passer par une déclaration standard puisque WriteBuf(var Buffer; BufferSize: Integer) induit le lecteur en erreur en pensant que le Buffer est susceptible d’être modifié dans le corps de la fonction alors que c'est pas le cas .. tu peux vérifier que Buffer est préfixé par la directive const dans la méthode Write de Stream..

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     ...
    for i := 0 to asr-1 do Dbuffer[i] := 0; // init buffer
    cette opération est superflue les tableaux dynamiques sont déjà initialisés à zéro!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     aTab2 := aTab1; // ça suffit à incrémenter le compteur de référence de 1 à 2
    il faut faire attention les tableaux dynamiques n'agissent pas toujours comme des pointeurs mais parfois ils se comportent comme les chaines string il arrive des fois que chaque variable ait sa propre copie du tableaux .
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    var
      A, B: array of integer;
    begin
      Insert([1, 2, 3, 4, 5], A, MAXINT);// ajouter des valeurs dans le tableau A
      B := A;
      SetLength(A,Length(A));
      if A <> B then
         raise Exception.Create('A et B n''utilisent pas le même tableau');

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 671
    Points : 13 065
    Points
    13 065
    Par défaut
    Citation Envoyé par tourlourou Voir le message
    Il y en a donc une !
    Je vois effectivement ici en bas de page que cette syntaxe est correct en FP.

    Dès lors le transtypage en cardinal n'a pas d'utilité.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Memo1.Lines.Add((PCardinal(aTab1) -1)^.ToHexString(8));

  19. #19
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 699
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 699
    Points : 15 042
    Points
    15 042
    Par défaut
    Bonjour et merci pour ces précisions.

    Juste un "détail" :
    Citation Envoyé par wheel Voir le message
    il faut faire attention les tableaux dynamiques n'agissent pas toujours comme des pointeurs mais parfois ils se comportent comme les chaines string il arrive des fois que chaque variable ait sa propre copie du tableau.
    Tu es en train de nous dire que les tableaux dynamiques ont un comportement... aléatoire ?
    Comme les machins quantiques ?
    Non mais au secours, quoi !
    Sur quoi faut-il se baser pour avoir une informatique fiable ?
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  20. #20
    Membre confirmé

    Homme Profil pro
    Retraité
    Inscrit en
    Avril 2012
    Messages
    170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2012
    Messages : 170
    Points : 455
    Points
    455
    Par défaut
    Bonjour,

    J'ai eu la curiosité de consulter la page en anglais du wiki "Dynamic array" de Lazarus, elle est beaucoup plus détaillée (et claire, c'est un comble) que celle en français, et évoque certains points de cette discussion.

    Ceci étant, et même si c'est pareil en Delphi (je ne sais pas pour C) ce n'est pas une bonne chose qu'on n'ait pas besoin de le traiter comme si c'était un "vrai" array et non comme un pointeur. La plupart des mésaventures qu'on peut rencontrer viennent de là. Au moins si on était obligé d'écrire MyDynArray[i]^ pour accéder à un élément sans que le compilo râle, on ne risquerait pas d'oublier que c'est un pointeur.

    Au fait peut-on écrire SizeOf(MyDynArray[i]^) pour avoir la taille de l'élément ?

    bb84000

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 1
    Dernier message: 26/04/2012, 15h05
  2. Réponses: 15
    Dernier message: 20/03/2008, 10h33
  3. tri des données différent entre 2 bases
    Par j6m dans le forum Oracle
    Réponses: 2
    Dernier message: 12/03/2006, 11h17
  4. [cr 8.5] comment exploiter les données d'un "array"
    Par kikidrome dans le forum SAP Crystal Reports
    Réponses: 12
    Dernier message: 09/06/2005, 15h03
  5. passage en paramètre d'un array dynamique 2D
    Par Guigui_ dans le forum Langage
    Réponses: 4
    Dernier message: 27/11/2002, 20h47

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