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 :

créer dynamiquement les paramètres d'une procédure


Sujet :

Langage Delphi

  1. #1
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut créer dynamiquement les paramètres d'une procédure


    Est-ce possible en Delphi ( ou avec l'Assembleur en ligne ) de créer dynamiquement la liste des paramètres d'une procédure/fonction ? par exemple la fonction que voici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    function DoAThing ( Param1 : Integer; Param2 : byte ) : Boolean;
    begin
    ...
    end;
    j'aurai aimé pouvoir faire quelque chose du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    for i := 0 to Length(Params)-1 do
     begin 
      Move(Params.ParamPointer,UnStack,Params.ParamSystemSize);
     end;
    Move(CallFunction(@DoAThing,UnStack),Pointer(Result)^,ResultSize);
    c'est possible ?

  2. #2
    Membre expert

    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Janvier 2004
    Messages
    2 123
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Responsable de service informatique

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 123
    Points : 3 256
    Points
    3 256
    Par défaut
    Salut,

    Pourquoi ne pas utiliser une TList en paramètre ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    function DoAThing ( ParamList : TList ) : Boolean;
    begin
    ...
    end;
    Comme cela, tu pourras choisir le type de chaque paramètre ainsi que le nombre de paramètres.
    CV :
    - LinkedIn
    - Viadeo

  3. #3
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    Oui mais pour par exemple faire un intérpréteur de script et ensuite charger une fonction avec LoadLibrary, ce serai utile de pouvoir reconstruire la liste des paramètres de façon dynamique ...

  4. #4
    Expert éminent sénior

    Avatar de Nono40
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2002
    Messages
    8 640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2002
    Messages : 8 640
    Points : 19 101
    Points
    19 101
    Par défaut
    Si j'ai bien compris tu veux pouvoir avec le même code appeller une fonction d'une dll dont la listes des paramètres est connue mais variable ?

    Il te faudra transmettre à ce code la liste des paramètres sous une certaine forme, puis dans le code d'empiler en assembleur tous les paramètres en fonction de ce qui est passé puis d'appeler la fonction ( toujours en assembleur ) de ta dll.

    Mine de rien ta question simple en apparence est compliquée à mettre en oeuvre.

    Est-ce que tes dll sont en fait des objets COM / Interfaces ? Ou des dlls classiques ?
    Delphi :
    La F.A.Q. , 877 réponses à vos questions !
    264 sources à consulter/télécharger !

  5. #5
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    c'est pour une dll classique. Je voudrais créer un interpréteur simple pour un de mes programmes ( juste quelque fonctions présentes dans l'api Windows ). Par exemple, pour exécuter le script
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    function MessageBox(Integer,PChar,PChar,Integer) : Integer;external "user32.dll" //si toutefois je me trompe pas de dll
    Je pourrai pas trop difficillement compiler un Integer comme un champ de 4 bytes en mémoire et un pchar comme un enregistrement de Char terminé par #0 grâce aux pointeurs. Mais alors comment empiler les paramètres en assembleur en ayant pour chaque type qu'un Pointeur indiquant sa valeur et un Integer indiquant la taille du Pointeur ?

    note. Je crois que le type PChar est plus un pointeur vers un champ de Char qu'autre chose, donc égallement comment définir le type Pointeur en assembleur ?

  6. #6
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Tiens, c'est marrant, moi aussi je cherche à faire un petit interpreteur simplissime, voici l'idée que j'ai creusé :

    Il s'agit d'utiliser par exemple un Paramètre de type TStrings :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    function DoAThing ( ParamList : TStrings ) : Boolean;
    begin
    ...
    end;
    En effet, à partir du TstringList, tu dois puvoir te faire un petit "scripting" maison assez facilement puisque chaque ligne du TStringList peut être écrite comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    param1=valeur1
    param2=valeur2
    param3=valeur3
    ...
    tu accèdes aux paramètres avec la propriété Names, et aux valeurs avec la propriété Values :

    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
     
    procedure Action1(AValue:string);
    begin
    ...
    end;
     
    procedure Action2(AValue:string);
    begin
    ...
    end;
     
    function DoAThing ( ParamList : TStrings ) : Boolean;
    var i:integer;
    begin
       for i:=0 to ParamList.Count-1 do
       begin
          if ParamList.Names[i]='Action1' then Action1(ParamList.Values[i]);
          if ParamList.Names[i]='Action2' then Action2(ParamList.Values[i]);
       end;
    end;

    tu as a ta disposition plein de propriété et methode intéressantes comme :
    • CommaText
      DelimitedText
      Delimiter
      Names
      NameValueSeparator
      QuoteChar
      Strings
      StringsAdapter
      Text
      ValueFromIndex
      Values



    A partir de là tu peux mème imaginer imbriquer des sous listes de paramètres pour te faire un système de boucle par exemple.


    Concrêtement, sur une fiche, tu met deux memos (memo1 est la sortie, memo2 le code en entrée), et un bouton :
    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 Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;
     
    type
      TForm1 = class(TForm)
        Memo1: TMemo;
        Memo2: TMemo;
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
        valeur,debut,fin,increment,DebutBoucle:integer;
        procedure ActionPRINT(AValue:string);
        procedure InitBoucle(ParamList : TStrings);
        function DoAThing ( ParamList : TStrings ) : Boolean;
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
    procedure TForm1.ActionPRINT(AValue:string);
    begin
       memo1.lines.add(AValue+' '+IntToStr(valeur));  //par exemple
    end;
     
    procedure TForm1.InitBoucle(ParamList : TStrings);
    var i:integer;
    begin
      increment:=1; //increment par defaut
      for i:=0 to ParamList.Count-1 do
       begin
          debut:=StrToInt(ParamList.Values['start']);
          increment:=StrToInt(ParamList.Values['step']);
          valeur:=debut;
       end;
    end;
     
    function TForm1.DoAThing ( ParamList : TStrings ) : Boolean;
    var Ligne:integer;
         AStringList:TStringList;
         fonction,parametres:string;
    begin
       Ligne:=0;
       while (Ligne<=ParamList.Count) do
       begin
          fonction:=ParamList.Names[Ligne];
          parametres:=ParamList.ValueFromIndex[Ligne];
          if fonction='FOR' then
          begin
             parametres:=copy(parametres,2,length(parametres)-2);
             AStringList:=TStringList.create;
             AStringList.delimiter:=';';
             AStringList.DelimitedText :=parametres;
             InitBoucle(AStringList);
             DebutBoucle:=Ligne;
             AStringList.Free;
          end;
          if fonction='ENDFOR' then
          begin
             fin:=StrToInt(parametres);
             Inc(valeur,increment);
             if (valeur<=fin) then
             begin
               Ligne:=DebutBoucle;
             end;
          end;
          if fonction='CLS' then memo1.Clear;
          if fonction='PRINT' then ActionPRINT(parametres);
          inc(Ligne);
       end;
    end;
     
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      DoAThing (memo2.Lines);
    end;
     
    end.
    A l'exécution et avant d'appuyer sur le bouton, dans memo2, tu écris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    //-Pas de signe egal dans les commentaires
    //-Signe egal obligatoire pour une instruction
    //-Lignes vides autorisées !!!
     
    //Efface le memo1
    CLS=0
     
    //Debut de boucle, step est facultatif
    FOR="start=1;step=2"
    //Affiche
    PRINT=coucou
    //Fin de boucle
    ENDFOR=10
    Bon courage
    Bidouilleuse Delphi

  7. #7
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    c'est une idée. Moi j'avais pensé utilisé un outil comme CocoR pour générer un Parser et même pouvoir compiler vers un PCode pour pouvoir mieux l'exécuter ( une sorte d'assembleur fait maison ) donc au lieu de devoir interpréter
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    MessageBox(0,"blabla","blabla",MB_ICONWARNING OR MB_YESNO);
    j'exécute
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    : define [Integer] Opx;
    : set Opx [MB_ICONWARNING] Or [MB_YESNO]
    : pcall [MessageBox] ;
    : add [Integer] 0 ;
    : add [String] "blabla" ;
    : add [String] "blabla" ;
    : add Opx;
    : call
    ce code est lourd mais c'est pas trop dur de l'exécuter car chaque étape est bien délimitée. Par contre j'aurai aimé pouvoir faire des procédures pour importer des dlls et donc construire quelque chose comme la lib d'Api Standard mais dans mon propre langage ( avec des external dans les principales dlls de Windows ) d'où mon envie de savoir comment on empile dynamiquement des paramètres pour appeller une fonction ( ou plutot un pointeur vers une fonction )

  8. #8
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    Vous voulez coder ces interpréteurs pour le plaisir (ou la fierté) d'en coder un ou bien pour l'utiliser dans une application. Si c'est la deuxième solution, alors je vous conseille à tous les deux la librairie Pascal Script de RemObjects qui fait exactement ce que vous voulez !
    http://www.remobjects.com/?ps
    sjrd, ancien rédacteur/modérateur Delphi.
    Auteur de Scala.js, le compilateur de Scala vers JavaScript, et directeur technique du Scala Center à l'EPFL.
    Découvrez Mes tutoriels.

  9. #9
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    je connais ce composant, mais les applications générées avec sont énormes ( par rapport à celles que j'ai ). Je voudrais compiler une application de moins de 100 Ko et en utilisant juste quelque fonctions de base ( avec l'appel de dlls ), je pense pouvoir faire en gros un truc de 80 Ko ...

  10. #10
    Membre du Club

    Inscrit en
    Juillet 2005
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 48
    Points : 58
    Points
    58
    Par défaut
    et si vous utilisiez le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    procedure maprocedure(params : array of const);
    begin 
      .....
    end;
     
    ou 
     
    function mafonction(params : array of const) : variant;
    begin
      ...
    end;
    nombre de paramétres indéfinis, et nombre de résultat infinis pour la fonction (objet, class, TStrings, .....) . Sans oublier que vous pouvez passer en paramétre n'importe quoi (objet, class, integer, ............)

  11. #11
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    ce serai bien si c'était mes dlls, mais pour la dll user32.dll, faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    function MessageBoxA ( params : Array of const ) : Variant;stdcall;external 'user32.dll';
    fait une violation d'accès. Je ne peut donc pas utiliser ce prototype de fonction pour mon script

  12. #12
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Citation Envoyé par sjrd
    Vous voulez coder ces interpréteurs pour le plaisir (ou la fierté) d'en coder un ou bien pour l'utiliser dans une application. Si c'est la deuxième solution, alors je vous conseille à tous les deux la librairie Pascal Script de RemObjects qui fait exactement ce que vous voulez !
    http://www.remobjects.com/?ps
    C'est sympa, je te remercie.

    Pour ton information, je suis en train de développer pour un usage concret une ActiveX et un plugin Netscape/Mozilla qui permette, à partir d'un fichier script en lien "embeded" ou "object" d'une page HTML de restituer un problème d'échecs ou une partie complète avec l'affichage de l'échiquier et des interaction avec l'utilisateur (un peu à la manière d'un flash maison).

    A l'arrivée, le but est que l'affichage et l'interaction soient pris en charge par l'applet ainsi créé à partir de commandes simples du style :
    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
     
    SET POSITION="tcfdrfctpppppppp                                         PPPPPPPPTCFDRFCT"
    PRINT="A vous de trouver la suite..."
    SET A=1
    GOTO=QUESTION
    LABEL=RECOMMENCER
    INC A=1
    IF A="3;SOLUTION"
    PRINT="Je suis sur que vous allez trouver !"
    LABEL=QUESTION
    ONMOVE="E2E4;SUITE;OTHER;RECOMMENCER"
    LABEL=SOLUTION
    PRINT="Solution : e4"
    MOVE="E2E4"
    LABEL=SUITE
    MOVE="E7E5;CGF3"
    Tu vois ce que j'essaies de faire ?
    Bidouilleuse Delphi

Discussions similaires

  1. Réponses: 3
    Dernier message: 31/05/2007, 02h41
  2. les paramétres d'une procédure
    Par popov2 dans le forum WinDev
    Réponses: 3
    Dernier message: 08/02/2007, 11h30
  3. Crypter les paramètres d'une procédure stockée
    Par aymron dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 19/09/2006, 10h52
  4. Passer le nom de colonne en paramètre d'une procédure stocké
    Par theartist dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 04/01/2005, 15h39
  5. Un fichier .bmp comme paramètre d'une Procédure stockée
    Par FONKOU dans le forum Bases de données
    Réponses: 2
    Dernier message: 28/10/2004, 17h56

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