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

Autres IDE Pascal Discussion :

Paramètre sous forme de constante non typée [Virtual Pascal]


Sujet :

Autres IDE Pascal

  1. #1
    Responsable Pascal, Lazarus et Assembleur


    Avatar de Alcatîz
    Homme Profil pro
    Ressources humaines
    Inscrit en
    Mars 2003
    Messages
    7 937
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ressources humaines
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2003
    Messages : 7 937
    Points : 59 414
    Points
    59 414
    Billets dans le blog
    2
    Par défaut Paramètre sous forme de constante non typée
    Bonjour à toutes et tous !

    Je butte sur le passage de paramètres sous forme de constantes non typées à une procédure ou à une fonction.
    Pour prendre un exemple : le paramètre Buffer de la fonction API WriteFile :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    function WriteFile (FileHandle: THandle; const Buffer;
                        NumberOfBytesToWrite: DWord; var NumberOfBytesWritten: DWord; 
                        Overlapped: POverlapped): Bool;
    Voici un bête programme d'essai :
    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
    42
    43
    Program ESSAI;
     
    Uses Strings, WinCRT, Windows;
     
    Var HandleFichier : tHandle;
        NomFichier : Array [0..MAX_PATH] of Char;
     
    Function CREATION_FICHIER (NomF : pChar; var HandleF : tHandle) : LongBool;
    Begin
      HandleF := CreateFile(NomF,GENERIC_WRITE,FILE_SHARE_WRITE,Nil,
                            CREATE_ALWAYS,FILE_ATTRIBUTE_ARCHIVE,0);
      CREATION_FICHIER := (HandleF <> INVALID_HANDLE_VALUE);
    End;
     
    Function ECRITURE_FICHIER (HandleF : tHandle; Chaine : pChar) : LongBool;
    Var NbBytesEcrits : DWord;
    Begin
      ECRITURE_FICHIER := WriteFile(HandleF,Chaine,StrLen(Chaine),NbBytesEcrits,Nil);
    End;
     
    Function FERMETURE_FICHIER (HandleF : tHandle) : LongBool;
    Begin
      FERMETURE_FICHIER := CloseHandle(HandleF);
    End;
     
    Begin
      InitWinCRT;
      StrCopy(NomFichier,'H:\Essai.txt');
      if CREATION_FICHIER(NomFichier,HandleFichier)
         then
           begin
             if not ECRITURE_FICHIER(HandleFichier,'Blabla')
                then
                  WriteBuf('Erreur '#233'criture',15);
             if not FERMETURE_FICHIER(HandleFichier)
                then
                  WriteBuf('Erreur fermeture',16);
           end
         else
           WriteBuf('Erreur cr'#233'ation',15);
      ReadKey;
      DoneWinCRT;     
    End.
    Dans la fonction ECRITURE_FICHIER, je passe un tableau de caractères comme paramètre. Dans le fichier résultat, il y a bien 6 caractères écrits mais... 6 caractères quelconques au lieu de 'Blabla'.

    Voici un extrait de l'output Assembleur :
    Code asm : 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
    		ALIGN DWORD
     
    ESSAI@ECRITURE_FICHIER PROC NEAR
    ;
    ; Function ECRITURE_FICHIER (HandleF : tHandle; Chaine : pChar) : LongBool;
    ; Var NbBytesEcrits : DWord;
    ; Begin
    ;
    		PUSH	EBP
    		MOV	EBP,ESP
    		SUB	ESP,8
    	      @@?0:
    ;
    ;   ECRITURE_FICHIER := WriteFile(HandleF,Chaine,StrLen(Chaine),NbBytesEcrits,Nil);
    ;
    		PUSH	0
    		LEA	EAX,[EBP-8]
    		PUSH	EAX
    		PUSH	DWORD PTR [EBP+8]
    		CALL	Strings@StrLen
    		PUSH	EAX
    		LEA	EAX,[EBP+8]
    		PUSH	EAX
    		PUSH	DWORD PTR [EBP+0Ch]
    		CALL	WriteFile
    ;
    ; End;
    ;
    		MOV	ESP,EBP
    		POP	EBP
    		RET	8
    ESSAI@ECRITURE_FICHIER ENDP

    Par contre, lorsque j'utilise un tableau de caractères local à la fonction ECRITURE_FICHIER, c'est bien 'Blabla' qui est écrit dans le fichier résultat.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Function ECRITURE_FICHIER (HandleF : tHandle; Chaine : pChar) : LongBool;
    Var NbBytesEcrits : DWord;
        ChaineLocale : Array [0..7] of Char;
    Begin
      StrCopy(ChaineLocale,Chaine);
      ECRITURE_FICHIER := WriteFile(HandleF,ChaineLocale,StrLen(ChaineLocale),NbBytesEcrits,Nil);
    End;
    Output Assembleur :
    Code asm : 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
    		ALIGN DWORD
     
    ESSAI@ECRITURE_FICHIER PROC NEAR
    ;
    ; Function ECRITURE_FICHIER (HandleF : tHandle; Chaine : pChar) : LongBool;
    ; Var NbBytesEcrits : DWord;
    ;     ChaineLocale : Array [0..7] of Char;
    ; Begin
    ;
    		PUSH	EBP
    		MOV	EBP,ESP
    		SUB	ESP,10h
    	      @@?0:
    ;
    ;   StrCopy(ChaineLocale,Chaine);
    ;
    		LEA	EAX,[EBP-10h]
    		PUSH	EAX
    		PUSH	DWORD PTR [EBP+8]
    		CALL	Strings@StrCopy
    ;
    ;   ECRITURE_FICHIER := WriteFile(HandleF,ChaineLocale,StrLen(ChaineLocale),NbBytesEcrits,Nil);
    ;
    		PUSH	0
    		LEA	EAX,[EBP-8]
    		PUSH	EAX
    		LEA	EAX,[EBP-10h]
    		PUSH	EAX
    		CALL	Strings@StrLen
    		PUSH	EAX
    		LEA	EAX,[EBP-10h]
    		PUSH	EAX
    		PUSH	DWORD PTR [EBP+0Ch]
    		CALL	WriteFile
    ;
    ; End;
    ;
    		MOV	ESP,EBP
    		POP	EBP
    		RET	8
    ESSAI@ECRITURE_FICHIER ENDP

    Ma question : quelqu'un pourrait-il m'aider à comprendre la différence entre les deux ?

    Citation Envoyé par Référence Virtual Pascal
    Constant parameters
    When a formal parameter is a constant parameter, it can be used like a local read-only variable in the
    procedure or function. The corresponding actual parameter substitutes the constant parameter when
    the function is called. The actual parameter must be an expression and the result of the expression
    cannot be of file type or any structured type containing a file type. The actual parameter must be
    assignment-compatible with the type of the formal parameter. A constant formal parameter can not be
    assigned values, or be passed as an actual variable parameter to another procedure or function.
    Constant parameters are passed in the same way as value parameters. However, when a value needs to
    be copied to the local stack of the routine, constant parameters are not copied as the compiler makes
    sure the variable is not written to. For this reason, it is better to use a constant formal parameter
    instead of a value formal parameter, if a formal parameter has the same value during the execution of
    a procedure or function. This protects it against accidental assignments and also lets the compiler
    generate more efficient code.
    Merci d'avance !
    Règles du forum
    Cours et tutoriels Pascal, Delphi, Lazarus et Assembleur
    Avant de poser une question, consultez les FAQ Pascal, Delphi, Lazarus et Assembleur
    Mes tutoriels et sources Pascal

    Le problème en ce bas monde est que les imbéciles sont sûrs d'eux et fiers comme des coqs de basse cour, alors que les gens intelligents sont emplis de doute. [Bertrand Russell]
    La tolérance atteindra un tel niveau que les personnes intelligentes seront interdites de toute réflexion afin de ne pas offenser les imbéciles. [Fiodor Mikhaïlovitch Dostoïevski]

  2. #2
    Rédacteur/Modérateur
    Avatar de M.Dlb
    Inscrit en
    Avril 2002
    Messages
    2 464
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Avril 2002
    Messages : 2 464
    Points : 4 311
    Points
    4 311
    Par défaut
    Salut mon cher !

    A priori, je verrais une histoire de pointeurs, de pile et de tas. Peut-être que l'utilisation de const oblige à chercher dans la pile, alors que dans ton premier cas, ta chaîne est dans le tas. On peut imaginer qu'il cherche l'adresse de ta chaîne dans la pile au lieu du tas, ce qui fait pointer sur un endroit non défini, d'où les caractères bizarres que tu obtiens... Mais ca semble très bizarre !
    M.Dlb - Modérateur z/OS - Rédacteur et Modérateur Pascal

  3. #3
    Membre expert
    Avatar de Eric Sigoillot
    Inscrit en
    Mars 2002
    Messages
    1 212
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 212
    Points : 3 369
    Points
    3 369
    Par défaut
    Hello !

    Ah ah, rien de bizarre là dedans

    C'est bien simple : dans ton deuxième exemple, tu passes à ta fonction un tableau de caractères (array of Char). Résultat des courses, c'est bien le tableau de caractères qui est écrit.

    Mais dans le premier exemple, tu passes une chaîne PChar, définie comme un pointeur vers un tableau de caractères. Résultat des courses, c'est la valeur du pointeur qui est écrite. Logique.
    Si tu vérifies, tu pourras constater que les 4 permiers caractères que tu retrouves dans ton fichier correspondent à l'adresse contenue dans ton PChar, et que les 2 restants sont issus de la mémoire (non prévisible facilement).

    Si tu veux que ça marche, essaie donc ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function ECRITURE_FICHIER(HandleF: THandle; Chaine: PChar): LongBool;
    var
      NbBytesEcrits: DWord;
    begin
      ECRITURE_FICHIER :=  WriteFile(HandleF, Chaine^, StrLen(Chaine), NbBytesEcrits, nil);
    end;
    Tu noteras que j'ai déréférencé le pointeur Chaine

    @++
    Règles du forum
    F.A.Q Pascal

    Pour me joindre (aucune question technique, merci)

  4. #4
    Responsable Pascal, Lazarus et Assembleur


    Avatar de Alcatîz
    Homme Profil pro
    Ressources humaines
    Inscrit en
    Mars 2003
    Messages
    7 937
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ressources humaines
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2003
    Messages : 7 937
    Points : 59 414
    Points
    59 414
    Billets dans le blog
    2
    Par défaut
    Bonjour,
    Citation Envoyé par Eric Sigoillot
    Tu noteras que j'ai déréférencé le pointeur Chaine
    Comment n'y ai-je pas pensé ? Je crois que c'est l'output Assembleur qui m'a troublé l'esprit.

    Merci mille fois Eric (et merci à Wormful pour t'être penché sur la question !)
    Règles du forum
    Cours et tutoriels Pascal, Delphi, Lazarus et Assembleur
    Avant de poser une question, consultez les FAQ Pascal, Delphi, Lazarus et Assembleur
    Mes tutoriels et sources Pascal

    Le problème en ce bas monde est que les imbéciles sont sûrs d'eux et fiers comme des coqs de basse cour, alors que les gens intelligents sont emplis de doute. [Bertrand Russell]
    La tolérance atteindra un tel niveau que les personnes intelligentes seront interdites de toute réflexion afin de ne pas offenser les imbéciles. [Fiodor Mikhaïlovitch Dostoïevski]

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 07/10/2013, 14h02
  2. Requête jpql et paramètres sous forme de Map
    Par Khaled.Noordin dans le forum JPA
    Réponses: 1
    Dernier message: 21/10/2011, 02h15
  3. Réponses: 5
    Dernier message: 04/05/2009, 23h47
  4. Visualiser des résultats sous forme d'un tableau (type Excel)
    Par meera dans le forum Interfaces Graphiques
    Réponses: 34
    Dernier message: 22/05/2007, 12h06

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