Déclaration de pointeur de fonction et structure
Voilà, j'ai un petit problème syntaxique
actuellement, j'ai ceci
Code:
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:
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:
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:
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:
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:
1 2 3 4
| PShaiMappingStruct = ^TShaiMappingStruct;
TShaiMappingStruct = record
...
end; |
et je lance un appel juste pour éviter d'écrire
Code:
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 ...