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 :

Comment mettre un fichier dans un PByte ? [Lazarus]


Sujet :

Lazarus Pascal

  1. #1
    Membre averti
    Homme Profil pro
    Paramétreur de progiciels
    Inscrit en
    Octobre 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Paramétreur de progiciels

    Informations forums :
    Inscription : Octobre 2006
    Messages : 970
    Points : 381
    Points
    381
    Par défaut Comment mettre un fichier dans un PByte ?
    Bonjour,

    J'ai une fonction qui attend un PByte, ce PByte est un buffer qui est le contenu d'un fichier.

    Je ne sais pas trop comment faire...

    J'ai essayé ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    var
        MonFichier : File;
        MonBuffer : PByte;
        MaTaille : Cardinal;
    begin
    AssignFile(MonFichier, ExtractFilePath(Application.ExeName) + MonFichierNom);
    Reset(MonFichier, 1);
    MaTaille := System.FileSize(MonFichier);
    GetMem(MonBuffer, MaTaille);
    BlockRead(MonFichier, MonBuffer^, MaTaille);
    System.Close(MonFichier);
    end;
    Je n'ai pas d'erreur mais ça ne semble pas fonctionner !

    EDIT :
    C'est un : unsigned char *
    Donc ce n'est peut-être pas un PByte mais plutôt un PChar.
    J'essaie de trouver une solution.

    Merci pour votre aide,
    ZiP

  2. #2
    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
    Tu peux essayer de passer @MonBuffer[0]

    La différence de déclaration PByte/PChar ne changera rien au comportement
    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 !

  3. #3
    Membre averti
    Homme Profil pro
    Paramétreur de progiciels
    Inscrit en
    Octobre 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Paramétreur de progiciels

    Informations forums :
    Inscription : Octobre 2006
    Messages : 970
    Points : 381
    Points
    381
    Par défaut
    Bonjour,

    J'ai modifié mon code, il se compile sans erreur 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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
     
    var
        MonFichier : TFileStream;
        MonBuffer : PChar; 
    begin
            MonFichier := TFileStream.Create(ExtractFilePath(Application.ExeName) + MonFichierNom, fmOpenRead);
            try
                GetMem(MonBuffer, MonFichier.Size);
                try
                    MonFichier.ReadBuffer(MonBuffer^, MonFichier.Size);
     
                    //Memo1.Lines.Add(MonBuffer);
     
                    Memo1.Lines.Add('-1');
     
                    while MonAcars.Decoder(MonBuffer) = ACD_SUCCESS do
                    begin
                         Memo1.Lines.Add('0');
                         Chaine := MonAcars.HumanReadable(0);
                         if Length(Chaine) = 0 then
                         begin
                             Memo1.Lines.Add('1');
                             MonNum := MonAcars.GoodOffset(Addr(i));
                             Chaine := MonAcars.ErrorsOfMsg(i);
                             Memo1.Lines.Add(Chaine);
                             Memo1.Lines.Add(' ');
                         end
                         else
                         begin
                              Memo1.Lines.Add('2');
                              Memo1.Lines.Add(Chaine);
                              Memo1.Lines.Add(' ');
                         end;
                    end;
                finally
                    FreeMem(MonBuffer);
                end;
            finally
                MonFichier.Free;
            end; 
    end;
    Un seul bémol, il ne fonctionne pas...

    Et je soupçonne un problème avec le PChar entre la DLL et le programme, je n'en suis pas sûr et je ne sais pas comment faire autrement...

    Vous trouverez ci-joint le code source complet de mon programme de test.

    Si vous pouviez m'aider à le faire fonctionner, ça serait très gentil !

    PS : La DLL semble faire planter le débogueur GDB, ça n'aide pas pour corriger le problème! Je pensai qie le problème venait du 64bits, mais en 32bits, ça plante aussi... IL faut donc lancer le programme en dehors de Lazarus après compilation.

    Merci,
    ZiP
    Fichiers attachés Fichiers attachés

  4. #4
    Expert confirmé
    Avatar de Ph. B.
    Homme Profil pro
    Freelance
    Inscrit en
    Avril 2002
    Messages
    1 784
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 784
    Points : 5 915
    Points
    5 915
    Par défaut
    Bonjour,
    Citation Envoyé par [ZiP] Voir le message
    Et je soupçonne un problème avec le PChar entre la DLL et le programme, je n'en suis pas sûr et je ne sais pas comment faire autrement...
    Il y a effectivement une belle et pourtant classique boulette dans le prototype des fonctions suivantes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        function acarsd_errors_of_msg(aLib: PAcarsd; const aOffset: Integer): String; stdcall; external 'libacarsd.dll' name 'acarsd_errors_of_msg@8';
    //
        function acarsd_human_readable(aLib: PAcarsd; const aForce: Integer): String; stdcall; external 'libacarsd.dll' name 'acarsd_human_readable@8';
    En pascal, la gestion des chaines de caractères est différente du C.
    Toute fonction C renvoyant ce type et interfacée en pascal doit être écrite avec un PChar (ou PAnsiChar ou PWideChar) !
    Cela donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        function acarsd_errors_of_msg(aLib: PAcarsd; const aOffset: Integer): PChar; stdcall; external 'libacarsd.dll' name 'acarsd_errors_of_msg@8';
    //
        function acarsd_human_readable(aLib: PAcarsd; const aForce: Integer): PChar; stdcall; external 'libacarsd.dll' name 'acarsd_human_readable@8';
    La libération de ces chaines doivent être gérées par l'appelant...
    Citation Envoyé par '[ZiP
    PS : La DLL semble faire planter le débogueur GDB, ça n'aide pas pour corriger le problème! Je pensai qie le problème venait du 64bits, mais en 32bits, ça plante aussi... IL faut donc lancer le programme en dehors de Lazarus après compilation.
    J'ai remarqué et je ne me suis pas engagé plus avant dans votre code qui encapsule la gestion de la dll...
    Mais j'ai traduit (à l’arrache il est vrai) le code C exemple fourni avec la dll, et apparemment cela fonctionne. J'obtiens 33 blocs valides, etc.
    Je n'ai pas remplacé certains codes par leur symbole : <13> par <CR>, <10> par <LF>, <22> par <SYN>, <21> par <NAK>, <2> par <STX>, <3> par <ETX> etc.
    Ci-joint, l'unité de traduction (une fiche avec un mémo, un bouton qui lance l'analyse du jeu d'essai).
    Fichiers attachés Fichiers attachés
    Philippe.

  5. #5
    Membre averti
    Homme Profil pro
    Paramétreur de progiciels
    Inscrit en
    Octobre 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Paramétreur de progiciels

    Informations forums :
    Inscription : Octobre 2006
    Messages : 970
    Points : 381
    Points
    381
    Par défaut
    Bonjour Ph. B.,

    Effectivement, après correction des String en PChar et avec votre code, ça fonctionne très bien !

    Par contre, avec mon code, ça ne fonctionne pas

    Vous pensez que c'est à cause de ma classe qui encapsule la DLL ?

    Merci,
    ZiP

  6. #6
    Expert confirmé
    Avatar de Ph. B.
    Homme Profil pro
    Freelance
    Inscrit en
    Avril 2002
    Messages
    1 784
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 784
    Points : 5 915
    Points
    5 915
    Par défaut
    Citation Envoyé par [ZiP] Voir le message
    Par contre, avec mon code, ça ne fonctionne pas

    Vous pensez que c'est à cause de ma classe qui encapsule la DLL ?
    Il y a forcément un truc mal codé quelque part dans cette classe...
    Je veux bien y jeter un oeil, mais malheureusement pour vous pas tout de suite. Je suis en train de finir un code Java que j'ai laissé de côté depuis trop longtemps...
    Désolé...
    Philippe.

  7. #7
    Membre averti
    Homme Profil pro
    Paramétreur de progiciels
    Inscrit en
    Octobre 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Paramétreur de progiciels

    Informations forums :
    Inscription : Octobre 2006
    Messages : 970
    Points : 381
    Points
    381
    Par défaut
    Je vais essayer de trouver par moi même

    Merci,
    ZiP

  8. #8
    Expert confirmé
    Avatar de Ph. B.
    Homme Profil pro
    Freelance
    Inscrit en
    Avril 2002
    Messages
    1 784
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 784
    Points : 5 915
    Points
    5 915
    Par défaut
    Citation Envoyé par [ZiP] Voir le message
    Je vais essayer de trouver par moi même
    J'ai trouvé, il m'a fallu 30 secondes !
    Il faut indiquer la bonne fréquence d’échantillonnage lors de la création de votre objet :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    MonAcars := TAcars.Create(FileSize(ExtractFilePath(Application.ExeName) + MonFichierNom), STREAM19500, 8);
    //MonAcars := TAcars.Create(FileSize(ExtractFilePath(Application.ExeName) + MonFichierNom), STREAM44100, 8);
    Ensuite, à votre place, je modifierais le constructeur et le destructeur comme suit :
    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
    type EAcarsException = Exception; // Classe d’exception à raffiner !
     
    constructor TAcars.Create(const aBufferSize: Integer; const aSampleRate: Integer; const aPassCount: Integer);
    begin
        inherited Create;
        fBufferSize := aBufferSize;
        fSampleRate := aSampleRate;
        fPassCount  := aPassCount;
        fLib := acarsd_init(fBufferSize, fSampleRate, fPassCount);
        if not Assigned(fLib) then
          raise EAcars.Create('Erreur d''initialisation !'); // A raffiner !
    end;
     
    destructor TAcars.Destroy;
    begin
        if Assigned(fLib) then
          acarsd_destroy(fLib);
        inherited Destroy;
    end;
    Philippe.

  9. #9
    Membre averti
    Homme Profil pro
    Paramétreur de progiciels
    Inscrit en
    Octobre 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Paramétreur de progiciels

    Informations forums :
    Inscription : Octobre 2006
    Messages : 970
    Points : 381
    Points
    381
    Par défaut
    Bonjour Ph. B.,

    Effectivement... C'était bien un problème de fréquence d’échantillonnage !

    Et maintenant ça marche parfaitement !

    Je vais essayer d'améliorer ma classe.

    Merci,
    ZiP

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 26/03/2010, 00h48
  2. Réponses: 0
    Dernier message: 03/12/2008, 17h43
  3. Réponses: 7
    Dernier message: 01/03/2007, 16h07
  4. Réponses: 1
    Dernier message: 20/11/2006, 02h16
  5. Comment mettre un tbitmap dans un fichier typé.
    Par poly128 dans le forum Delphi
    Réponses: 7
    Dernier message: 16/10/2006, 01h00

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