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. #1
    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 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 chevronné
    Avatar de Droïde Système7
    Homme Profil pro
    Inscrit en
    Septembre 2003
    Messages
    2 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 2 262
    Points : 1 928
    Points
    1 928
    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 à 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
    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 chevronné
    Avatar de Droïde Système7
    Homme Profil pro
    Inscrit en
    Septembre 2003
    Messages
    2 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 2 262
    Points : 1 928
    Points
    1 928
    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 à 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
    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 : 38
    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
    Points : 4 935
    Points
    4 935
    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

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

    Informations forums :
    Inscription : Septembre 2003
    Messages : 2 262
    Points : 1 928
    Points
    1 928
    Par défaut
    Bonsoir,

    Par contre, une chose que j'aurais évité : la déclaration de ta fiche "integration" ici en "interface".

    Mais la placer, (comme l'autre fiche) au dessous "implementation".

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    unit DGL1D_Interface_ThermionicEmission;
     
    interface
     
    uses Dialogs,SysUtils,DGL1D_Interface,grdpnt,Direction_Parent, Math, integration;
    @+

  8. #8
    Membre éprouvé
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    Points : 1 294
    Points
    1 294
    Par défaut
    hahaha.

    le truc est tout con : theta veux un paramètre et tu l'appel sans donc le compilo t'envois bouler.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    V := truc(machin, theta); // ne compile pas
     
    V := truc(machin, theta(0)); // compile
    on peu également légérement optimiser theta :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    function theta(xx:Extended):Extended;
    begin
      if xx<0 then result := 1 else result := 0;
    end;
    [ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ]
    Ma messagerie n'est pas la succursale du forum... merci!

  9. #9
    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
    Merci pour toutes vos réponses.

    Dr. Who : non, le paramètre qui rentre en argument doit vraiment être une fonction (theta) et non une valeur de cette fonction (theta(0)). J'ai essayé dans le doute et ça ne marche effectivement pas!

    Droïde Système7 : ok, c'est déplacé!

    ero-sennin : oui j'avais pensé à cette solution en étudiant un peu les histoires de visibilité. Mais il me semble que ça revient exactement au même que de définir ma fonction à intégrer en dehors de ma procédure. Je voulais éviter ça mais apparemment je ne vais pas y louper...

    PS : juste une petite idée : est-ce qu'il y une différence entre fonction et procédure en ce qui concerne mon problème (histoire de visibilité,etc)? Car pour l'instant ma fonction qui intègre est une fonction, mais je pourrais tout à fait utiliser une procédure.

    Si quelqu'un a encore une idée, je suis preneur!!
    Bonne journée,
    Helber

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

    Informations forums :
    Inscription : Septembre 2003
    Messages : 2 262
    Points : 1 928
    Points
    1 928
    Par défaut
    Revenons aux fondamentaux : combien de fiches (visibles ou non) comporte cette appli, à part la principale et celle en question ?

    @+

  11. #11
    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
    Si par fiche tu entends fichier .pas, alors il y en a une centaine je dirais (à vu de nez!). Je ne suis pas l'architecte du programme en question ; j'essaie juste de le développer. Et mon but est de pouvoir intégrer une fonction définie à peu près n'importe où dans mon programme, sans avoir à réécrire l'algorithme d'intégration dans chaque fiche.

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

    Informations forums :
    Inscription : Septembre 2003
    Messages : 2 262
    Points : 1 928
    Points
    1 928
    Par défaut
    [...] il y en a une centaine je dirais (à vu de nez!).
    Hé hé...

    En ce cas, je te propose de délarder / réduire le problème : de copier ce projet dans un autre dossier bien distinct et de le réduire.

    Ce qui signifie que tu dois virer toutes les autres fiches, afin qu'il ne t'en reste plus que tes deux en question.

    Je sais, je suis déjà passé par là = les erreurs, suite aux manques que cela va engendré.

    Mais c'est un chemin qui devrait te diriger vers la réponse que tu cherches.

    A toi de voir

    Car avec deux fiches, c'est tout de même plus simple à modifier et enfin détecter ce qui marchait en crabe.

    @+ et bon courage

  13. #13
    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
    Hummm. Non, je ne préfère pas chambouler l'organisation du programme pour "si peu". Je ne suis pas le seul à le développer, et je suis le p'tit dernier sur l'affaire. Alors peut-être plus tard!

    Par contre j'ai une autre idée : ce qui m'embête dans le fait de devoir déclarer ma fonction en dehors de la procédure, c'est que dans la procédure j'utilise des variables locales que je veux garder locales, et que je ne peux donc pas utiliser dans la définition de ma fonction (qui est non locale à la procédure). Pour contourner ce problème, je pense définir la fonction avec en argument un tableau et sa taille. Dans la définition de ma fonction qui intègre, je rajouterai en argument un numéro (position de la variable dans le tableau sur laquelle je veux faire l'intégration)...
    Bref c'est un peu tordu mais ça devrait marcher et en plus rajouter la possibilité d'intégrer par rapport à n'importe quelle variable de la fonction.

    Je vous tiens au courant
    Merci

  14. #14
    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
    Non, l'idée présentée ci-dessus n'était pas une bonne idée... ça fait vraiment dégueulasse comme procédure et trop compliqué à manier par la suite...

    Après réflexion, je ne vois pas la différence entre mon cas et le suivant :
    -dans mon programme il y a un "package" (une unit) math où la fonction cosinus par exemple est "définie" (cf ci-dessous)
    -dans l'unit où je travaille je dois appeler math au début
    -et ensuite je peux utiliser cos(v) n'importe où, peu importe où v est définie (variable globale ou locale)

    Donc pourquoi quand je crée une fonction dans ma procédure (une variable comme une autre après tout) et que je la passe en argument dans ma fonction intégration (l'équivalent de cos à mes yeux), ça pose un problème?

  15. #15
    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 : 38
    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
    Points : 4 935
    Points
    4 935
    Par défaut
    Je ne comprends pas ton souci.
    Pourquoi tu ne sors tout simplement pas la fonction de la procédure ?
    Tu as ceci :

    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
    //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;
    Donc forcément, ça ne fonctionne pas (cf mon message précédent).
    Suffit de faire ceci :

    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
     
    //Heavyside function
    function theta(xx:Extended):Extended;
    begin
      result := 0;
      if xx<0 then result :=1;
    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; 
    begin
     
    inte:=Integrale(1.0,2.0,theta);
     
    end;
    Et logiquement ça compile
    Ce que je ne comprends pas, c'est pourquoi tu veux éviter de la sortir ?

  16. #16
    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
    Oui, je pourrais avec theta. ça ne pose pas de problème pour cette fonction.

    Mais par la suite (c'est-à-dire, dès que j'ai résolu le problème de l'intégration) je vais avoir à définir des fonctions (à intégrer) qui seront définis avec des variables locales à la procédure (comme si theta utilisait dxint par exemple dans sa définition).

    Et parce qu'il est conseillé de travailler avec des variables locales, j'aurais aimé conserver le caractère local de ces variables. Ce qui m'oblige (enfin je pense) à définir ma fonction dans la procédure même, une fois que ces variables ont elles-même étaient définies.

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 740
    Points : 13 285
    Points
    13 285
    Par défaut
    Concernant l'erreur 2094, il y a une façon assez simple de leurrer le compilateur. Il suffit de passer à ta fonction un pointer non typé

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    inte := Integrale(1.0, 2.0, @theta);

  18. #18
    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
    Alors, ça marche un peu mieux. L'ajout du "@" permet de faire passer la fonction définie dans la procédure en argument de Integrale.

    Maintenant, quand j'utilise une variable définie peu importe où (soit globale à l'unit, soit local à la procédure), ça plante. La compilation se fait sans problème apparent, mais quand j'exécute le programme ça break à l'endroit où la variable externe à la fonction est appelée (dans cette même fonction) :

    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
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    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;
    
    
    
    
    //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;
    
    
      function test(B: extended): extended;
    begin
      result :=dEv*B;
    end;
    
    begin
    
    
    //initialisation
    for i:=1 to anzDGL do for j:=1 to anzDgl do begin
      gp.DGL_0[i,j]:=0;
      gp.DGL_0Im[i,j]:=0;
      gp.DGL_F[i,j]:=0;
    //???  gp.fmc[i,j]:=0;
      gp.DGL_B[i,j]:=0;
      end;
    
    dEv := sign *  (nb.Eg - gp.Eg + nb.chi - gp.chi); 
    
     inte:=integrale(1.0,2.0,@test);
    
    end;
    Je remets integration :

    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
    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;
     
    end.
    Le message d'erreur exact est :
    First chance exception at $75E99617. Exception class EAccessViolation with message 'Access violation at address 00709A11 in module 'prog.exe'. Read of address FFFFFFFC'. Process prog.exe (2192)
    Je précise que le problème est bien lié à integration car si j'appelle la fonction "simplement" (inte:=test(3); par exemple) je n'ai pas d'erreur.

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 740
    Points : 13 285
    Points
    13 285
    Par défaut
    Ca fonctionne avec theta parce que tu ne fais qu'un test sur le paramètre. Mais tu ne peux pas utiliser une variable définie dans la procédure conteneur puisque l'appel ne se fait pas depuis cette procédure.
    Ca devrait fonctionner avec une variable globale, pour autant qu'elle n'ait pas le même nom qu'une variable du conteneur .

  20. #20
    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
    Non ça ne marche pas.... même avec une variable globale (déclarée globale, mais attribuée dans la procédure)

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