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

cerber943 33 Messages postés lundi 20 janvier 2003Date d'inscription 26 octobre 2006 Dernière intervention - 29 oct. 2004 à 14:34 - Dernière réponse : cs_Bestiol 871 Messages postés dimanche 6 janvier 2002Date d'inscription 3 novembre 2005 Dernière intervention
- 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 

19 réponses

Répondre au sujet
ZeWaren 24 Messages postés vendredi 11 juin 2004Date d'inscription 22 février 2005 Dernière intervention - 29 oct. 2004 à 20:49
+3
Utile
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 ?
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de ZeWaren
cs_Delphiprog 4580 Messages postés samedi 19 janvier 2002Date d'inscription 9 janvier 2013 Dernière intervention - 3 nov. 2004 à 22:07
+3
Utile
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
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de cs_Delphiprog
jinh68 215 Messages postés mardi 29 juillet 2003Date d'inscription 1 septembre 2006 Dernière intervention - 29 oct. 2004 à 14:40
0
Utile
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
JulioDelphi 2354 Messages postés dimanche 5 octobre 2003Date d'inscription 18 novembre 2010 Dernière intervention - 29 oct. 2004 à 14:42
0
Utile
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
jinh68 215 Messages postés mardi 29 juillet 2003Date d'inscription 1 septembre 2006 Dernière intervention - 29 oct. 2004 à 14:52
0
Utile
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
JulioDelphi 2354 Messages postés dimanche 5 octobre 2003Date d'inscription 18 novembre 2010 Dernière intervention - 29 oct. 2004 à 15:19
0
Utile
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
cs_leveugle 27 Messages postés lundi 8 mars 2004Date d'inscription 18 novembre 2004 Dernière intervention - 29 oct. 2004 à 15:40
0
Utile
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
JulioDelphi 2354 Messages postés dimanche 5 octobre 2003Date d'inscription 18 novembre 2010 Dernière intervention - 29 oct. 2004 à 23:38
0
Utile
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
cs_Delphiprog 4580 Messages postés samedi 19 janvier 2002Date d'inscription 9 janvier 2013 Dernière intervention - 30 oct. 2004 à 02:29
0
Utile
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
cs_neko 135 Messages postés jeudi 14 août 2003Date d'inscription 12 octobre 2006 Dernière intervention - 30 oct. 2004 à 17:48
0
Utile
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
jinh68 215 Messages postés mardi 29 juillet 2003Date d'inscription 1 septembre 2006 Dernière intervention - 30 oct. 2004 à 20:04
0
Utile
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
cs_neko 135 Messages postés jeudi 14 août 2003Date d'inscription 12 octobre 2006 Dernière intervention - 30 oct. 2004 à 20:44
0
Utile
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
cs_Delphiprog 4580 Messages postés samedi 19 janvier 2002Date d'inscription 9 janvier 2013 Dernière intervention - 30 oct. 2004 à 21:52
0
Utile
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
cerber943 33 Messages postés lundi 20 janvier 2003Date d'inscription 26 octobre 2006 Dernière intervention - 3 nov. 2004 à 09:53
0
Utile
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
cs_Delphiprog 4580 Messages postés samedi 19 janvier 2002Date d'inscription 9 janvier 2013 Dernière intervention - 3 nov. 2004 à 22:58
0
Utile
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
jinh68 215 Messages postés mardi 29 juillet 2003Date d'inscription 1 septembre 2006 Dernière intervention - 4 nov. 2004 à 08:39
0
Utile
Respect pour ces recherches fructueuses, serait-il possible que tu fasses un petit tutorial la dessus? :)

j!nH
Commenter la réponse de jinh68
cs_leveugle 27 Messages postés lundi 8 mars 2004Date d'inscription 18 novembre 2004 Dernière intervention - 4 nov. 2004 à 09:11
0
Utile
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
cs_Delphiprog 4580 Messages postés samedi 19 janvier 2002Date d'inscription 9 janvier 2013 Dernière intervention - 6 nov. 2004 à 10:46
0
Utile
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
cs_Bestiol 871 Messages postés dimanche 6 janvier 2002Date d'inscription 3 novembre 2005 Dernière intervention - 25 août 2005 à 23:21
0
Utile
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.