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

Delphi Discussion :

Déclaration de pointeur de fonction et structure


Sujet :

Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 086
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 086
    Par défaut Déclaration de pointeur de fonction et structure
    Voilà, j'ai un petit problème syntaxique

    actuellement, j'ai ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    type
      TShaiMappingStruct = record
        ShaiName : string;        // Champ dans la Table Shai
        DestName: string;         // Champ dans la Table Dest
        SetProc: Pointer;         // Procédure d'Affectation du Champ Dest
        SourceValue: string;      // Champ qui sera comparé au Champ Shai
        DestinationValue: string; // Champ qui sera affecté au Champ Dest
        RelationName: string;     // Champ dans la Table Shai qui sert pour un Test
      end;
      TShaiMappingSetter = procedure(const Item: TShaiMappingStruct; const Source, Destination: TDataSet);
    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
    // Affectation Simple
    procedure StandardSetter(const Item: TShaiMappingStruct; const Source, Destination: TDataSet);
    var
      SourceField, DestinationField: TField;
    begin
      SourceField := Source.FindField(Item.ShaiName);
      DestinationField := Destination.FindField(Item.DestName);
      if Assigned(SourceField) and Assigned(DestinationField) and not SourceField.IsNull and IsEmptyDest(DestinationField) then
        DestinationField.AsVariant := SourceField.AsVariant;
    end;
     
    // Affectation d'une Constante en fonction de la Valeur de la Source
    procedure TestConstSetter(const Item: TShaiMappingStruct; const Source, Destination: TDataSet);
    var
      SourceField, DestinationField: TField;
    begin
      SourceField := Source.FindField(Item.ShaiName);
      DestinationField := Destination.FindField(Item.DestName);
      if Assigned(SourceField) and Assigned(DestinationField) and not SourceField.IsNull and IsEmptyDest(DestinationField) then
      begin
        if SourceField.AsString = Item.SourceValue then
          DestinationField.AsVariant := Item.DestinationValue;
      end;
    end;
     
    // ... Quelques autres Setter encore ...
    j'ai l'association entre les champs et leur fonction

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    const
      Shai_MAPPING : array[TShaiMapping] of TShaiMappingStruct =
      (
        (ShaiName: 'Champ1';                  DestName: 'ChampOne';         SetProc: @TestConstSetter; SourceValue: '...'; DestinationValue: '...'),
        (ShaiName: 'Champ2';                  DestName: 'ChampTwo';         SetProc: @WithoutPointSetter),
        (ShaiName: 'Champ3';                  DestName: 'ChampThree';       SetProc: @StandardSetter),
        (ShaiName: 'Champ4';                  DestName: 'ChampFor';         SetProc: @RelativeSetter;  SourceValue: '...'; RelationName: 'RelationName'),
    ...

    et enfin, j'ai les appels

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
          // Copie des Champs de la Table Shai vers une Autre Table selon le Mapping
          for iMapping := Low(iMapping) to High(iMapping) do
            TShaiMappingSetter(Shai_MAPPING[iMapping].SetProc)(Shai_MAPPING[iMapping], Shai, Destination);
    Le problème c'est que l'on pourrait très vite écrire du code sans aucun contrôle du compilateur, donc je voulais remplacer pointer par le type de procédure ...


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
      TShaiMappingStruct = record
        ShaiName : string;        // Champ dans la Table Shai
        DestName: string;         // Champ dans la Table Dest
        SetProc: TShaiMappingSetter;         // Procédure d'Affectation du Champ Dest
        SourceValue: string;      // Champ qui sera comparé au Champ Shai
        DestinationValue: string; // Champ qui sera affecté au Champ Dest
        RelationName: string;     // Champ dans la Table Shai qui sert pour un Test
      end;
      TShaiMappingSetter = procedure(const Item: TShaiMappingStruct; const Source, Destination: TDataSet);
    Mais peu importe que l'on le mette avant ou après, l'un ne trouve pas l'autre

    alors que ceci fonctionne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    PShaiMappingStruct = ^TShaiMappingStruct;
    TShaiMappingStruct = record
       ...
    end;
    et je lance un appel juste pour éviter d'écrire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    type
    PShaiMappingStruct = ^TShaiMappingStruct;
    TShaiMappingSetter = procedure(const Item: PShaiMappingStruct; const Source, Destination: TDataSet);  
    TShaiMappingStruct = record
      end;
    cela permet de retirer l' @ dans le tableau (faut juste en mettre un dans la boucle),
    cela permet de retirer aussi le cast du pointeur en procédure
    cela garanti l'adéquation des paramètres ... mais comme je suis tatillons, je me sens obligé de mettre les ^ pour déférencer les Item explicitement ...

    alors j'ai tenté une autre syntaxe, avec un pointer de procédure mais du coup, cela ne fait la vérification des paramètres ...

    Ma Question est comment faire la même chose sans tricher avec le pointer ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  2. #2
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 491
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 491
    Par défaut
    salut

    ce que tu veut faire n'est pas possible de facon statique
    avec les pointer le comilo ne fait pas le test

    sinon une bete question ca n'aurait pas ete plus simple de passer par une class avec des procedure of object

    @+ Phil

  3. #3
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 086
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 086
    Par défaut
    J'ai changé ma Syntaxe, j'ai utilisé la méthode du dernier bloc en trichant avec PShaiMappingStruct, est comme ça dans ma structure j'ai un TShaiMappingSetter au lieu d'un pointeur, donc cela contrôle, ... mais c'est juste que je trouve cela dommage d'avoir la possibilité d'avoir une déclaration forward quand l'on déclare un type de pointeur et pas pour une fonction ... mais bon ...

    avec les pointer le comilo ne fait pas le test
    quel test ?
    celui des paramètres de la procédure
    celui de l'existant du type sur lequel on créé un pointeur ? "PTruc = ^Truc;" car tu peux pas faire un pointeur sur un type qui n'existe pas !

    Sinon pour les Procédure d'objet (genre les gestionnaire d'Events), ... le problème c'est que j'ai du mal à voir comment remplacer mon tableau avec ce principe de classe, ... si tu as une proposition de syntaxe je suis preneur, ... le but étant tout de même d'avoir un code ultra générique et ultra compact ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  4. #4
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 491
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 491
    Par défaut
    salut

    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
    Type
    TProcSetter = Procedure (Sender : Tobject; const Source, Destination:TDataSet) of object;  
     
    TShaiMappingStruct = Class
        ShaiName : string;        // Champ dans la Table Shai
        DestName: string;         // Champ dans la Table Dest
        SourceValue: string;      // Champ qui sera comparé au Champ Shai
        DestinationValue: string; // Champ qui sera affecté au Champ Dest
        RelationName: string;     // Champ dans la Table Shai qui sert pour un Test
        SetProc: TProcSetter;         // Procédure d'Affectation du Champ Dest
       Constructor Create( ShaiName ,DestName, SourceValue,estinationValue
        ,RelationName: string)      
     end;
     
    TarrayShaiMappingStruct =  array of  TShaiMappingStruct;
     
    procedure MyForm.CreateForm(...);
    var 
      Arr : TarrayShaiMappingStruct;
    begin
      setlength(Arr,1);
      arr[0] := TShaiMappingStruct.create('Champ1', 'ChampOne','...','...'   );
      arr[0].SetProc := StandardSetter;
      setlength(Arr,length(Arr));
      arr[high(Arr)] := TShaiMappingStruct.create('Champ2', 'ChampTo','...','...'   );
      arr[high(Arr)].SetProc := TestConstSetter;
      ...
    end;
    // Affectation Simple
    procedure MyForm.StandardSetter(Sender : Tobject; const Source, Destination: TDataSet);
    var
      SourceField, DestinationField: TField;
    begin
      SourceField := Source.FindField(Item.ShaiName);
      DestinationField := Destination.FindField(Item.DestName);
      if Assigned(SourceField) and Assigned(DestinationField) and not SourceField.IsNull and IsEmptyDest(DestinationField) then
        DestinationField.AsVariant := SourceField.AsVariant;
    end;
     
    // Affectation d'une Constante en fonction de la Valeur de la Source
    procedure MyForm.TestConstSetter(Sender : Tobject; const Source, Destination: TDataSet);
    var
      SourceField, DestinationField: TField;
    begin
      SourceField := Source.FindField(Item.ShaiName);
      DestinationField := Destination.FindField(Item.DestName);
      if Assigned(SourceField) and Assigned(DestinationField) and not SourceField.IsNull and IsEmptyDest(DestinationField) then
      begin
        if SourceField.AsString = Item.SourceValue then
          DestinationField.AsVariant := Item.DestinationValue;
      end;
    end;
    quand au test c'est celui de la "coherence" du pointer
    bien sur que si tu dis que c'est un pointer sur le type il faut que celui-ci exist
    mais tu pourrait tous aussi bien

    dire que
    @+ Phil

  5. #5
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 086
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 086
    Par défaut
    Effectivement, ta proposition est exactement ce que je pensais que cela donnerait, c'est extrément long, tu perds l'énumération qui permet de gérer proprement le nombre d'élement, le code à maintenir est plus long (le mapping est sur 30 champs déjà, et non pas que 4 comme mon extrait)

    le Sender : Tobject en TObjet n'a aucun intéret ! il faut caster dans les Setter ... donc on arrive à la possibilité d'erreur d'execition que l'on aurait pu résoudre directement à la compilation, le but était de passer en paramètre un TShaiMappingStruct, tout en ayant TProcSetter dans cette classe, mais avec les classes ce problème ce résoud par une déclaration Forward .

    deplus faudra libérer les objets, donc autant passer par une TObjectList au lieu d'un tableau évidemmeent ...

    Désolé d'être aussi critique, je cherche vraiement le code le plus "optimum" car on a bcp de code inutile dans notre programme qui pourrait être refactorer avec une méthode standardisée comme celle-ci
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  6. #6
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 491
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 491
    Par défaut
    salut

    Tu peut Peut etre dans ce cas passer une list de champs plutot
    que de passer champs par champs

    je ne t'ai donnée qu'une des possibilite ne connaissant pas le probleme dans ca globalite

    le sender peut avoir un interet pour connaitre l'element declanchant
    si tu nomme tes objects

    tu peut aussi passer par une collection si tu lui passe des tfield
    ou encore par un tableau de champs

    il y as une multitude de solution

    @+ Phil

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

Discussions similaires

  1. classe sans déclaration et pointeur de fonction
    Par Asmod_D dans le forum C++
    Réponses: 3
    Dernier message: 27/06/2010, 16h39
  2. structures et pointeurs de fonctions
    Par aimad41 dans le forum C
    Réponses: 5
    Dernier message: 21/11/2006, 10h49
  3. Structure, pointeur et fonction...
    Par Linaa dans le forum C
    Réponses: 15
    Dernier message: 04/12/2005, 13h12
  4. Pointeur de fonction et structure
    Par Trunks dans le forum C
    Réponses: 6
    Dernier message: 07/10/2005, 00h32
  5. Réponses: 4
    Dernier message: 08/02/2005, 20h47

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