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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 51
    Par défaut Visibilité d'une fonction déclarée dans une procédure
    Bonjour,

    Ce message fait suite à la discussion "Intégration numérique d'une fonction" que j'ai crée. Mais ne savant pas comment changer le titre du sujet, je crée cette nouvelle discussion.
    J'ai ("on", avec l'aide des forumers) créé une unit (integration.pas)dans lequel est définie une fonction qui prend en argument une fonction et 2 bornes d'intégration, et qui en retour donne l'intégrale de cette fonction entre ces bornes.
    Ensuite, je me mets dans une autre unit, j'appel l'unit Integration, je déclare une fonction test que je veux intégrer entre 1 et 2 par exemple et j'écris integration(1,2,test).
    Problème : ça marche seulement si ma fonction test est définie en dehors de ma procédure.
    Un membre a suggéré que c'était du à un problème de visibilité, sans pouvoir m'en dire plus. J'ai cherché un peu et me suis renseigné sur cette histoire de visibilité mais ne comprends toujours pas. Surtout que si j'utilise ma fonction test en tant que fonction (test(3) par exemple), ça marche. Mais si je la passe en argument de integration, j'ai le message
    [DCC Error] DGL1D_Interface_ThermionicEmission.pas(364): E2094 Local procedure/function 'theta' assigned to procedure variable
    Je mets ci-dessous l'unit integration.pas :

    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
     
    unit Integration;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;
    type
      TOperation = function(X: Extended): Extended;
     
      function Integrale(X1,X2 : Extended; Fonction: TOperation): Extended;
     
    implementation
     
       function Integrale(X1,X2 : Extended; Fonction: TOperation): Extended;
    Var
       N, i : Integer ;
       Somme, XDeb, XFin, Pas : Extended ;
       YDeb, YFin : Extended ;
    begin
      N := 100 ;
      Somme := 0 ;
      Pas := (X2 - X1)/N ;
      For i := 1  to N Do
         Begin
            XDeb := X1 + (i-1) * Pas ;
            XFin := Xdeb + Pas ;
            YDeb :=  Fonction(XDeb) ;
            YFin :=  Fonction(XFin) ;
            Somme := Somme + (YDeb + YFin) / 2 * Pas ;
         End ;
      result := Somme ;
    end;
     
    end.
    et l'unit où je l'utilise :

    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
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    unit XXX;
    
    interface
    
    uses ...,integration;
    
    
    type
    
    XXX =  class(Z)
    
      inte:extended;
    
    
      // DGLsystem to be solved
      procedure DGLSys; override;                      //DC mode DGL
    
    
    end;
    
    
    
    implementation
    
    
    uses ...;
    
    
    function test(B: extended): extended;
    begin
      result := B*5;
    end;
    
    //steady-state DC DGLSys, Thermionic Emission Interface
    procedure TDGL1D_Interface_ThermionicEmission.DGLSys;
    
    
    var
    
      dxInt :extended;       
    
      //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); //ceci ne marche pas avec theta, mais marche avec test
    
    theta(1); //ceci marche
    
    end;
    Merci d'avance pour votre aide.
    Helber

  2. #2
    Membre Expert
    Avatar de Droïde Système7
    Homme Profil pro
    Inscrit en
    Septembre 2003
    Messages
    2 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 2 288
    Par défaut
    Salut,

    Regardé vite fait... surtout à cause de l'indentation

    Mais tu n'as pas renseigné l'implementation de ta fiche "Integration", bref ce qui donne le droit au pointage vers ta fiche principale.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    [...]
      function Integrale(X1,X2 : Extended; Fonction: TOperation): Extended;
     
    implementation
    
    uses
     ICI !!! => XXX; 
     
       function Integrale(X1,X2 : Extended; Fonction: TOperation): Extended;
    Var
    
    [...]
    @+

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 51
    Par défaut
    Humm... j'ai essayé mais ça me met le message :
    [DCC Error] DGL1D_Interface_ThermionicEmission.pas(5): F2047 Circular unit reference to 'DGL1D_Interface_ThermionicEmission'
    Je remets le fichier, mieux indenté je pense (!) :

    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
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    unit DGL1D_Interface_ThermionicEmission;
     
    interface
     
    uses Dialogs,SysUtils,DGL1D_Interface,grdpnt,Direction_Parent, Math,integration;
     
     
    type
    // Semiconductor-Semiconductor Thermionic-Emission Interface
    TDGL1D_Interface_ThermionicEmission =  class(TDGL1D_Interface)
     
      ae  :extended; //richardson constant electrons
      ah  :extended; //richardson constant holes
      me  :extended;
      mh  :extended;
      meffe: Extended;
      meffh: Extended;
      f1:Extended;
      k1:Extended;
      inte:extended;
     
     
      // DGLsystem to be solved
      procedure DGLSys; override;                      //DC mode DGL
      procedure DGLSysAc(omega:extended);override;     //AC mode DGL
      procedure DGLSysTransient(dt:Extended);override; //TR mode DGL
     
    end;
     
     
     
    implementation
     
     
    uses HeteroJunctionMain,type_def,ParameterIO,constants,Direction_Interface,
         Direction_Interface_TE,ModelParametersTE;
     
     
    //function theta(xx:Extended):Extended;
    function test(B: extended): extended;
    begin
      result := B*5;
    end;
     
    //steady-state DC DGLSys, Thermionic Emission Interface
    procedure TDGL1D_Interface_ThermionicEmission.DGLSys;
     
     
    var
     
      dxInt :extended;       //dimensionless distance from the gridpoint to the interface
      PoissonFact :extended; //scaling factor of the dimensionless poisson equation
      AeNeu,AhNeu :Extended; // Richardson current
      dEc, dEv    :Extended; // conduction band offset, valence band offset
      inTherm :Extended;     // electron thermal emission current across the interface
      ipTherm :Extended;     // hole thermal emission current across the interface
      inTherm_n, inTherm_nNB :Extended; //derivates  _n  _nNB (at neighbour gridpoint)
      ipTherm_p, ipTherm_pNB :Extended; //derivates  _p  _pNB (at neighbour gridpoint)
      i,j                   :Integer;
      sign: extended;
      deltE,delth: extended;
     
     
      //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;
    et Integration.pas, où j'ai rajouté le DGL1D_Interface_ThermionicEmission:

    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
    unit Integration;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls,DGL1D_Interface_ThermionicEmission;
     
    type
      TOperation = function(X: Extended): Extended;
     
      function Integrale(X1,X2 : Extended; Fonction: TOperation): Extended;
     
    implementation
     
       function Integrale(X1,X2 : Extended; Fonction: TOperation): Extended;
    Var
       N, i : Integer ;
       Somme, XDeb, XFin, Pas : Extended ;
       YDeb, YFin : Extended ;
    begin
      N := 100 ;
      Somme := 0 ;
      Pas := (X2 - X1)/N ;
      For i := 1  to N Do
         Begin
            XDeb := X1 + (i-1) * Pas ;
            XFin := Xdeb + Pas ;
            YDeb :=  Fonction(XDeb) ;
            YFin :=  Fonction(XFin) ;
            Somme := Somme + (YDeb + YFin) / 2 * Pas ;
         End ;
      result := Somme ;
    end;
     
    end.

  4. #4
    Membre Expert
    Avatar de Droïde Système7
    Homme Profil pro
    Inscrit en
    Septembre 2003
    Messages
    2 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 2 288
    Par défaut
    Oui c'est un peu mieux indenté, ouffff

    références circulaires...

    Tu as tartiné de "DGL1D_Interface_ThermionicEmission" un peu partout

    Faudrait déjà t'appliquer à nommer plus clairement certaines choses, afin de ne pas t'embrouiller les pinceaux.

    Exemple : "DGL1D_Interface_ThermionicEmission" pourrait devenir "DGL1D_ITE".

    Mais bon, chaque programmeur possède ses habitudes.

    Je te souhaite bon ménage

    Cherche sur le forum via les mots clés "référence circulaire".

    Edit : tu n'as pas exactement placé ta déclaration au bon endroit, ainsi que je te le montrais.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 51
    Par défaut
    Oui effectivement, pardon. J'ai rectifié le tir, et je me retrouve avec le premier message d'erreur...

    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
    unit Integration;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;
     
    type
      TOperation = function(X: Extended): Extended;
     
      function Integrale(X1,X2 : Extended; Fonction: TOperation): Extended;
     
    implementation
     
    uses DGL1D_Interface_ThermionicEmission;
     
       function Integrale(X1,X2 : Extended; Fonction: TOperation): Extended;
    Var
       N, i : Integer ;
       Somme, XDeb, XFin, Pas : Extended ;
       YDeb, YFin : Extended ;
    begin
      N := 100 ;
      Somme := 0 ;
      Pas := (X2 - X1)/N ;
      For i := 1  to N Do
         Begin
            XDeb := X1 + (i-1) * Pas ;
            XFin := Xdeb + Pas ;
            YDeb :=  Fonction(XDeb) ;
            YFin :=  Fonction(XFin) ;
            Somme := Somme + (YDeb + YFin) / 2 * Pas ;
         End ;
      result := Somme ;
    end;

  6. #6
    Rédacteur/Modérateur
    Avatar de ero-sennin
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2005
    Messages
    2 965
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2005
    Messages : 2 965
    Par défaut
    Salut,

    Je viens de tester le code, et en effet, ça ne fonctionne pas. D'ailleurs, Delphi non dit pourquoi :

    Ce message d'erreur est émis si vous essayez d'affecter une procédure locale à une variable procédure ou de la transmettre comme paramètre procédure.

    Ceci est incorrect car la procédure locale pourrait alors être appelée même si la procédure incluse n'est pas active. Cette situation peut provoquer un plantage du programme si la procédure locale essaie d'accéder à une variable de la procédure incluse.

    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
    program Produce;
     
    var
      P : Procedure;
     
    procedure Outer;
     
      procedure Local;
      begin
        Writeln('Local s''exécute');
      end;
     
    begin
      P := Local;       (*<-- Message d'erreur ici*)
    end;
     
    begin
      Outer;
      P;
    end.
    L'exemple essaie d'affecter une procédure locale à une variable locale. Ceci est incorrect car l'exécution n'est pas sécurisée.

    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
    program Solve;
     
    var
      P : Procedure;
     
    procedure NonLocal;
    begin
      Writeln('NonLocal s''exécute');
    end;
     
    procedure Outer;
     
    begin
      P := NonLocal;
    end;
     
    begin
      Outer;
      P;
    end.
    La solution consiste à déplacer la procédure locale hors de celle incluse.
    Reste à l'appliquer dans ton cas

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