Appel de Fonction de façon "dynamique"

Résolu
cerber943 Messages postés 32 Date d'inscription lundi 20 janvier 2003 Statut Membre Dernière intervention 26 octobre 2006 - 29 oct. 2004 à 14:34
cs_Bestiol Messages postés 833 Date d'inscription dimanche 6 janvier 2002 Statut Membre Dernière intervention 3 novembre 2005 - 25 août 2005 à 23:21
Bonjour,

Je souhaite savoir s'il est possible d'appeler une fonction en ayant son nom dans une variable sans pour autant faire une sorte d'interprétteur.

En gros, je souhaiterais être à même de créer une procédure :
procedure appel_fonction(nom_fonction : String);
mais je ne souhaite pas effectuer de comparaison du contenu de nom_fonction pour effectuer le traitement associé.

Je ne sais pas si j'ai été clair...
J'espère en tout cas que quelqu'un pourra me répondre/comprendre et me donner une piste à suivre :)

merci d'avance

19 réponses

ZeWaren Messages postés 24 Date d'inscription vendredi 11 juin 2004 Statut Membre Dernière intervention 22 février 2005
29 oct. 2004 à 20:49
Jette un coup d'oeil la dessus et dit nous si ca peut t'aider :http://www.swissdelphicenter.ch/en/showcode.php?id=799

http://www.jansfreeware.com/articles/delphi-call-by-name.html

J'espere avoir pu aider...

Pourquoi remetre à demain ce qu'on peut faire après demain ?
3
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
3 nov. 2004 à 22:07
Qu'est-ce qui ifférencie une DLL d'un EXE ?
Eh bien, dans une DLL il faut déclarer les fonctions visibles de l'extérieur dans une clause Exports !
Alors pourquoi cela ne marcherait-il pas aussi avec un exe ?
Voici le code qui vérifie (avec succès :) :) ) cette hypothèse.

procedure Test;
begin
  ShowMessage('Procédure Test');
end;

function FindProc(ProcName: string): string;
var
  H: HModule;
  P: procedure;
begin
  Result := EmptyStr;

  H := GetModuleHandle(nil);
  if H <> 0 then
  begin
    P := GetProcAddress(H, PChar(ProcName));
    if Assigned(P) then
    begin
      P;
      Result := Format('"%s" found at %p', [ProcName, @@P]);
    end
    else
      Result := ProcName + ' not found';
  end;
end;

procedure TForm1.btnFindProcClick(Sender: TObject);
begin
  Memo1.Lines.Add(FindProc(EdProcName.Text));
end;

exports
  Test;


Toute l'astuce est donc dans cette dernière partie avec sa clause exports !
Et dire que c'était si simple... :-p
Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
May Delphi be with you
3
jinh68 Messages postés 215 Date d'inscription mardi 29 juillet 2003 Statut Membre Dernière intervention 1 septembre 2006
29 oct. 2004 à 14:40
En fait je comprends ce que tu veux faire, mais ca me semble compliqué, le seul moment ou jai vu qu'on pouvait identifier une fonction par un nom( PChar) c'était quand tu appelles une fonction d'une dll à l'aide de GetProcAddress...

Mais doit ya avoir un moyen, je vais regarder ça..

Dans quel but précis veux tu faire ça?

j!nH
0
JulioDelphi Messages postés 2226 Date d'inscription dimanche 5 octobre 2003 Statut Membre Dernière intervention 18 novembre 2010 14
29 oct. 2004 à 14:42
hello,

explique moi l'interet de cette procedure ?
pourquoi ne pas simplement lancer tes fonctions ?

tu peux par exemple faire :
procedure appel_fonction(nom_fonction : String);
begin
if nom_fonction = Fonction1 then Fonction1 else
if nom_fonction = Fonction2 then Fonction2 else
if nom_fonction = Fonction3 then Fonction3;
...
end;


ça te va ? c ce que tu cherches ?

N'oubliez pas de cliquer sur Réponse acceptée lorsque la réponse vous convient ! ;)

-------------------------------------------
http://diabloporc.free.fr : mon site refait ! Delphi power !
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
jinh68 Messages postés 215 Date d'inscription mardi 29 juillet 2003 Statut Membre Dernière intervention 1 septembre 2006
29 oct. 2004 à 14:52
Non à mon avis pas, il a bien précisé qu'il ne voulait pas faire de comparaison :-).

j!nH
0
JulioDelphi Messages postés 2226 Date d'inscription dimanche 5 octobre 2003 Statut Membre Dernière intervention 18 novembre 2010 14
29 oct. 2004 à 15:19
oups dsl ! j'ai été trop vite en besogne :/

bon et bien alors je ne connais pas d'autre soluce pour le moment ...

N'oubliez pas de cliquer sur Réponse acceptée lorsque la réponse vous convient ! ;)

-------------------------------------------
http://diabloporc.free.fr : mon site refait ! Delphi power !
0
cs_leveugle Messages postés 27 Date d'inscription lundi 8 mars 2004 Statut Membre Dernière intervention 18 novembre 2004
29 oct. 2004 à 15:40
Salut,

je ne comprends pas (non plus) bien pourquoi tu ne veux pas faire de comparaison sur nom_fonction ...

si ton objectif est d'éxécuter une fonction directement à partir de la chaîne nom_fonction, ce n'est possible qu'à condition
que les fonctions à appeler soient des méthodes (publiques?) d'un objet et en faisant appel aux RTTI. (Run Time Type Infos).

Dans le cas contraire, tu peux aussi construire un tableau à deux dimensions (String, pointeur sur fonctions ) à conditions que toutes les fonctions à appler aient le même prototype.

Damien
0
JulioDelphi Messages postés 2226 Date d'inscription dimanche 5 octobre 2003 Statut Membre Dernière intervention 18 novembre 2010 14
29 oct. 2004 à 23:38
WOW
superbe code !
a garder en favoris :)
merci ZeWaren ;)

N'oubliez pas de cliquer sur Réponse acceptée lorsque la réponse vous convient ! ;)

-------------------------------------------
http://diabloporc.free.fr : mon site refait ! Delphi power !
0
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
30 oct. 2004 à 02:29
OK, le code est bien, mais il ne s'applique qu'à des méthodes et non à des procédures ou fonctions "toutes simples", autrement dit celles qui ne sont pas "of object".

Affaire à suivre...

May Delphi be with you
0
cs_neko Messages postés 135 Date d'inscription jeudi 14 août 2003 Statut Membre Dernière intervention 12 octobre 2006 1
30 oct. 2004 à 17:48
non, ca s'applique tres bien a n'importe quelle variable, ce code marche impec, il suffit de definir les procedures avec le meme nombre de param et le meme type.

  TProcedure2Param = procedure(Param1, Param2: String);

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Déclarations privées }
  public
    { Déclarations publiques }
  end;

Procedure Stuff(Param1, Param2: String);
Procedure ReStuff(Param1, Param2: String);

var
  Form1: TForm1;
  Procedure2Param: TProcedure2Param;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  @Procedure2Param := @Stuff;
  Procedure2Param('a', 'b');
  @Procedure2Param := @ReStuff;
  Procedure2Param('a', 'b');
end;

Procedure Stuff(Param1, Param2: String);
Begin
  ShowMessage('Stuff');
End;
Procedure ReStuff(Param1, Param2: String);
Begin
  ShowMessage('ReStuff');
End;


bouh
0
jinh68 Messages postés 215 Date d'inscription mardi 29 juillet 2003 Statut Membre Dernière intervention 1 septembre 2006
30 oct. 2004 à 20:04
Certes, mais ce n'est pas ce que demande cerber943, il veut appeler ces fonctions et procédures par l'intermédiaire d'un string ;)!

j!nH
0
cs_neko Messages postés 135 Date d'inscription jeudi 14 août 2003 Statut Membre Dernière intervention 12 octobre 2006 1
30 oct. 2004 à 20:44
ha oui, autant pour moi j'avais mal lu ce qu'il demandait, je m'en escuse ^^
bouh
0
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
30 oct. 2004 à 21:52
Après avoir fait un grand tour de la question et cherché un peu partout, il apparaitrait que ce ne soit pas possible, du moins sans entrainer des complications démesurées.

Il te reste donc la solution, facile et efficace cette fois-ci, de mettre ces fonctions à appeler dans une DLL. Après tout, n'est-ce pas le rôle des DLL à l'origine que d'être des bibliothèques de fonctions que l'on appelle par leur nom ?

Est-ce un problème pour toi ?
Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
May Delphi be with you
0
cerber943 Messages postés 32 Date d'inscription lundi 20 janvier 2003 Statut Membre Dernière intervention 26 octobre 2006
3 nov. 2004 à 09:53
Merci beaucoup pour toutes vos réponses et désolé de n'avoir pu répondre plus tôt.
Pour ceux qui se demandent qu'elle peut être l'utilité d'appeler des fonctions par leur nom, cela a pour but de pouvoir définir dans un fichier des règles de calcul de quotients familials qui évoluent fréquemment au cours du temps et dont la gestion appartient plus à mes utilisateurs qu'à moi (ils font l'objet d'une réglementation clairement définie).

Un interpretteur serait le bienvenu mais je n'ai absoluement pas le temps de faire évoluer.
Je pense qu'en agissant ainsi, je pourrais rapidement ajouter des modification de calcul de Q.F. (même si ce n'est certainement pas la méthode la plus propre/conventionnelle.

N'ayant encore jamais conçu de DLL, je n'envisagais pas cette solution. Néanmoins puisqu'elle est la plus apropriée, je prendrais du temps pour m'y intéresser de plus près.

Merci pour les liens postés qui m'ont apporté la majore partie de la réponse que j'attendais.
J'espère m'en sortir en passant des paramètres par adresse pour utiliser mes procédures comme des fonctions... (je n'ai pas encore essayé).

Encore merci pour toutes vos réponses.

Cordiallement
0
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
3 nov. 2004 à 22:58
Encore un détail ou astuces, c'est comme vous voudrez.

Si vous voulez vérifier de manière encore plus forte, utilisez la commande "Voir/Fenêtres de débogage/Modules" dans les menus de Delphi quand votre EXE est en cours d'exécution.
Cliquez sur le nom de votre exécutable dans la liste des processus et recherchez le nom de la procédure Test dans la liste située à droite dans la boite de dialogue. Vous verrez, juste à côté, l'adresse de la procédure. Un double clic sur la ligne et hop, Delphi positionne le curseur de l'éditeur dans la procédure Test.

Et hop ! La boucle est bouclée :big) :big)
Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
May Delphi be with you
0
jinh68 Messages postés 215 Date d'inscription mardi 29 juillet 2003 Statut Membre Dernière intervention 1 septembre 2006
4 nov. 2004 à 08:39
Respect pour ces recherches fructueuses, serait-il possible que tu fasses un petit tutorial la dessus? :)

j!nH
0
cs_leveugle Messages postés 27 Date d'inscription lundi 8 mars 2004 Statut Membre Dernière intervention 18 novembre 2004
4 nov. 2004 à 09:11
Alors la j'applaudis des deux boutons de ma souris... !
(et j'en profite pour fiare un copier coller dans astuces en tout genre....)

euh dis t'as essayé un import de test dans un exe autre ?

Damien
0
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
6 nov. 2004 à 10:46
jinh68 : je ne vois pas trop comment faire un tutoriel avec 2 ou 3 lignes de code comme simple démonstration. Faire un ocde source ? pourquoi pas, mais le mieux serait de trouver comment appeler une procédure dans un autre exe (sans passer par la création d'un serveur COM hors processus). Donc je mets de côté pour l'instant. Merci en tous cas pour ces encouragements.

leveugle : je crois que j'ai répondu à ta question en répondant à jinh68. Continuons à chercher. Mais comme il existe au moins une solution à ce problème, je me sens moins motivé pour le faire.

Si vous êtes impatients, je vous recommande la lecture du tutoriel CREER et utiliser un serveur OLE AUTOMATION sur le site de Michel BARDOU.

Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
May Delphi be with you
0
cs_Bestiol Messages postés 833 Date d'inscription dimanche 6 janvier 2002 Statut Membre Dernière intervention 3 novembre 2005 1
25 août 2005 à 23:21
Regardez du côté de LoadLibraryEx, elle permet normalement de charger un EXE comme une DLL (jamais fait de test)

0
Rejoignez-nous