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 :

Visibilité d'une fonction déclarée dans une procédure


Sujet :

Langage Delphi

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 693
    Points : 13 128
    Points
    13 128
    Par défaut
    Si, si, j'ai essayé .

    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
    type
      TTestProc = procedure;
     
      TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
      end;
     
    var
      Form1: TForm1;
      Var1 :string;
     
    implementation
     
    {$R *.dfm}
     
    procedure CallProc(aProc :TTestProc);
    begin
      aProc;
    end;
     
    procedure DoCall;
     
      procedure Test;
      begin
        ShowMessage(Var1);
      end;
     
    begin
      Var1 := 'Hello world!';
      CallProc(@Test);
    end;
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      DoCall;
    end;
     
    end.

  2. #22
    Expert confirmé

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Points : 4 170
    Points
    4 170
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    procedure TDGL1D_Interface_ThermionicEmission.DGLSys;
    var
      dxInt : extended;       //dimensionless distance from the gridpoint to the interface
      //Heavyside function
      function theta(xx:Extended):Extended;
      begin
        result := 0;
        if xx<0 then result :=1;
      end;
     
    begin
      inte := Integrale(1.0,2.0,theta); 
    end;
    Il faut bien comprendre la signification d'une déclaration locale : L'élément n'est visible et n'existe que dans le contexte où il a été déclaré.

    La fonction theta est définie localement dans DGLSys. Tu peux y faire appel n'importe où dans DGLSys, et comme theta est locale à DGLSys, elle peut également faire appel aux variables locales de DGLSys.

    Par contre, ta fonction Integrale est une fonction globale. Elle est définie à l'extérieur de DGLSys. Elle ne peut pas savoir ce qui se passe dans DGLSys. En particulier, elle ne peut pas accéder aux variables locales de DGLSys.
    Lorsque tu passes theta en paramètre à Integrale, il faut bien avoir conscience que tu demandes à Integrale d'appeler la fonction theta.
    Mais theta risque d'avoir besoin d'utiliser les variables locales de DGLSys. Sauf qu'on se trouve dans Integrale, qui ne connait pas les variables locales de DGLSys.
    Si le compilateur te laissait faire, lorsque theta va essayer d'accéder aux variables locales de DGLSys, elle va s'imaginer qu'elle est dans le contexte d'exécution de DGLSys, et va aller chercher les variables comme si on se trouvait dans DGLSys. Sauf que comme on se trouve en réalité dans Integrale, theta va aller chercher n'importe quoi et les conséquences risquent d'être catastrophiques.
    C'est pourquoi le compilateur contrôle ce genre de chose et t'interdit de le faire.

    La solution de Andnotor est une ruse de sioux qui permet de tromper le compilateur pour qu'il ne puisse pas faire de contrôle à la compilation. Cependant ça ne veut pas dire que ça marchera dans tous les cas.
    On utilise ce genre de ruse lorsqu'on sait ce qu'on fait et qu'on maîtrise les effets de bords que ça risque d'engendrer (autrement dit, on sait que pour ce qu'on fait, ça marchera).
    En ce qui te concerne, ce n'est clairement pas ton cas, donc tu fairais mieux d'oublier cette solution.

    Par rapport à ce que tu veux, tu as deux solutions :
    - Soit tu définis Integrale également comme une fonction locale à DGLSys, ce qui devrait te permettre de lui passer theta en paramètre (à vérifier qu'en même...), mais tu ne pourras pas appeler Integrale en dehors de DGLSys. C'est assez moyen...
    - Soit tu définis theta, et toutes tes fonctions à intégrer comme étant des fonctions "globales" (ou privée à l'implémentation). Et si tu dois les paramétrer, tu passes soit par un paramètre supplémentaire, soit par des variables globales (le code sera plus propre avec un paramètre...).

    Maintenant tu peux aussi faire un peu de POO au lieu de tout faire en impératiif, et ça ouvre la porte à tout un tas de possibilités...

  3. #23
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 51
    Points : 15
    Points
    15
    Par défaut
    Ok merci.
    Pour ta première solution, est-ce que tu parles de réécrire la fonction integrale dans chaque procédure où elle sera utilisée, ou y-a-t'il un moyen de la déclarer en dehors de la procédure (comme maintenant) mais de l'appeler de façon locale dans la procédure?
    Pour la deuxième solution, quand tu parles de "paramètre supplémentaire", tu parles d'arguments de la fonction (par exemple écrire f(x,m1,m2,...) au lieu de f(x))?
    A+

  4. #24
    Expert confirmé

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Points : 4 170
    Points
    4 170
    Par défaut
    Citation Envoyé par Helber Voir le message
    Pour ta première solution, est-ce que tu parles de réécrire la fonction integrale dans chaque procédure où elle sera utilisée, ou y-a-t'il un moyen de la déclarer en dehors de la procédure (comme maintenant) mais de l'appeler de façon locale dans la procédure?
    La définir de façon locale signifie la réécrire dans chaque procédure où elle sera utilisée.
    Il y a néanmoins quelques bidouilles qui pourraient être testée pour ne pas écrire le code à chaque fois :
    - mettre sa définition dans un fichier externe et faire un include du fichier dans la procédure... pas très beau, ça produirait son effet, mais le code serait qu'en même dupliqué dans l'exe.
    - On peut essayer de définir Integrale comme une fonction globale, mais en la déclarant inline. Le fait de la rendre inline la transformerait en une sorte de macro : Lorsqu'on appelle Integrale, le compilateur ne fera pas un appel à la fonction inline, mais injectera directement le code de la fonction à l'endroit de l'appel. Du coup, sur le principe la fonction Integrale pourait faire appel aux fonctions locales de la procédure où elle est appelée. Mais je ne sais pas si le compilateur laissera faire...
    Dans tous les cas, le code de Integrale sera dupliquée autant de fois que d'endroit où on l'appellerait.
    Ca reste donc de la bidouille, et il vaut mieux éviter...

    Pour la deuxième solution, quand tu parles de "paramètre supplémentaire", tu parles d'arguments de la fonction (par exemple écrire f(x,m1,m2,...) au lieu de f(x))?
    C'est ça. Tu prévois deux paramètres pour la fonction ; f(x, UserData). Avec un type assez générique pour UserData (genre un pointeur sur une structure, de façon à pouvoir fournir plusieurs valeurs si la fonction à besoin de plusieurs paramètres).
    Evidemment, il faudra aussi ajouter un paramètre à Integrale : La valeur à transmettre à UserData pour chaque calcul de f(x).

  5. #25
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 51
    Points : 15
    Points
    15
    Par défaut
    Ok merci. Je vais essayer une des solutions "bidouilles", en gardant bien en tête que ça devra être amélioré dans un futur pas trop lointain! Peut-être quand j'en saurai un peu plus sur la POO si ça peut résoudre ces problèmes de visibilité...

Discussions similaires

  1. Réponses: 10
    Dernier message: 14/03/2009, 13h36
  2. [AJAX] [XAJAX] Lancer une fonction JS dans une fonction AJAX
    Par sixieme-sens dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 26/12/2008, 15h26
  3. Réponses: 1
    Dernier message: 25/10/2007, 21h25
  4. Réponses: 10
    Dernier message: 18/04/2007, 17h17
  5. [VBA-E] Une fonction Excel dans une fonction VBA
    Par laloune dans le forum Macros et VBA Excel
    Réponses: 10
    Dernier message: 14/07/2006, 10h21

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