Appel de Fonction de façon "dynamique" [Résolu]

Messages postés
33
Date d'inscription
lundi 20 janvier 2003
Dernière intervention
26 octobre 2006
- - Dernière réponse : cs_Bestiol
Messages postés
871
Date d'inscription
dimanche 6 janvier 2002
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
Afficher la suite 

Votre réponse

19 réponses

Meilleure réponse
Messages postés
24
Date d'inscription
vendredi 11 juin 2004
Dernière intervention
22 février 2005
3
Merci
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 ?

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources a aidé 106 internautes ce mois-ci

Commenter la réponse de ZeWaren
Messages postés
4580
Date d'inscription
samedi 19 janvier 2002
Dernière intervention
9 janvier 2013
3
Merci
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

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources a aidé 106 internautes ce mois-ci

Commenter la réponse de cs_Delphiprog
Messages postés
215
Date d'inscription
mardi 29 juillet 2003
Dernière intervention
1 septembre 2006
0
Merci
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
Commenter la réponse de jinh68
Messages postés
2354
Date d'inscription
dimanche 5 octobre 2003
Dernière intervention
18 novembre 2010
0
Merci
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 !
Commenter la réponse de JulioDelphi
Messages postés
215
Date d'inscription
mardi 29 juillet 2003
Dernière intervention
1 septembre 2006
0
Merci
Non à mon avis pas, il a bien précisé qu'il ne voulait pas faire de comparaison :-).

j!nH
Commenter la réponse de jinh68
Messages postés
2354
Date d'inscription
dimanche 5 octobre 2003
Dernière intervention
18 novembre 2010
0
Merci
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 !
Commenter la réponse de JulioDelphi
Messages postés
27
Date d'inscription
lundi 8 mars 2004
Dernière intervention
18 novembre 2004
0
Merci
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
Commenter la réponse de cs_leveugle
Messages postés
2354
Date d'inscription
dimanche 5 octobre 2003
Dernière intervention
18 novembre 2010
0
Merci
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 !
Commenter la réponse de JulioDelphi
Messages postés
4580
Date d'inscription
samedi 19 janvier 2002
Dernière intervention
9 janvier 2013
0
Merci
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
Commenter la réponse de cs_Delphiprog
Messages postés
135
Date d'inscription
jeudi 14 août 2003
Dernière intervention
12 octobre 2006
0
Merci
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
Commenter la réponse de cs_neko
Messages postés
215
Date d'inscription
mardi 29 juillet 2003
Dernière intervention
1 septembre 2006
0
Merci
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
Commenter la réponse de jinh68
Messages postés
135
Date d'inscription
jeudi 14 août 2003
Dernière intervention
12 octobre 2006
0
Merci
ha oui, autant pour moi j'avais mal lu ce qu'il demandait, je m'en escuse ^^
bouh
Commenter la réponse de cs_neko
Messages postés
4580
Date d'inscription
samedi 19 janvier 2002
Dernière intervention
9 janvier 2013
0
Merci
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
Commenter la réponse de cs_Delphiprog
Messages postés
33
Date d'inscription
lundi 20 janvier 2003
Dernière intervention
26 octobre 2006
0
Merci
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
Commenter la réponse de cerber943
Messages postés
4580
Date d'inscription
samedi 19 janvier 2002
Dernière intervention
9 janvier 2013
0
Merci
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
Commenter la réponse de cs_Delphiprog
Messages postés
215
Date d'inscription
mardi 29 juillet 2003
Dernière intervention
1 septembre 2006
0
Merci
Respect pour ces recherches fructueuses, serait-il possible que tu fasses un petit tutorial la dessus? :)

j!nH
Commenter la réponse de jinh68
Messages postés
27
Date d'inscription
lundi 8 mars 2004
Dernière intervention
18 novembre 2004
0
Merci
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
Commenter la réponse de cs_leveugle
Messages postés
4580
Date d'inscription
samedi 19 janvier 2002
Dernière intervention
9 janvier 2013
0
Merci
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
Commenter la réponse de cs_Delphiprog
Messages postés
871
Date d'inscription
dimanche 6 janvier 2002
Dernière intervention
3 novembre 2005
0
Merci
Regardez du côté de LoadLibraryEx, elle permet normalement de charger un EXE comme une DLL (jamais fait de test)

Commenter la réponse de cs_Bestiol

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.