Création dynamique de fonctions
Le
baruchel
Jusqu'où peut-on aller de façon totalement portable pour créer
dynamiquement
des fonctions? Je m'explique. Supposons un petit jeu de fonctions de
prototype
void func(void), rien n'empêche d'allouer une certaine quantité de
mémoire,
d'y mettre dans l'ordre souhaité, l'adresse des fonctions à exécuter,
puis
de lancer l'exécution à l'aide d'une fonction "interface", qui
exécuterait
toutes les fonctions à partir de leur adresse jusqu'à rencontrer un
pointeur NULL pour marquer l'arrêt. La solution est ici totalement
standard. Peut-on
alléger le processus, notamment en se passant de cette boucle
d'exécution ?
Dans la mesure où toutes les fonctions à exécuter ont le même
prototype, est-il
possible de constituer en mémoire un code exécutable appelant
successivement
les fonctions, dans la mesure où la fonction censée être ainsi créée
ne comporterait ni boucle, ni test, mais se contenterait d'appeler
dans l'ordre
des fonctions sans argument à partir de leur adresse? Est-il possible
de faire cela sans quitter la portabilité du C standard ?
dynamiquement
des fonctions? Je m'explique. Supposons un petit jeu de fonctions de
prototype
void func(void), rien n'empêche d'allouer une certaine quantité de
mémoire,
d'y mettre dans l'ordre souhaité, l'adresse des fonctions à exécuter,
puis
de lancer l'exécution à l'aide d'une fonction "interface", qui
exécuterait
toutes les fonctions à partir de leur adresse jusqu'à rencontrer un
pointeur NULL pour marquer l'arrêt. La solution est ici totalement
standard. Peut-on
alléger le processus, notamment en se passant de cette boucle
d'exécution ?
Dans la mesure où toutes les fonctions à exécuter ont le même
prototype, est-il
possible de constituer en mémoire un code exécutable appelant
successivement
les fonctions, dans la mesure où la fonction censée être ainsi créée
ne comporterait ni boucle, ni test, mais se contenterait d'appeler
dans l'ordre
des fonctions sans argument à partir de leur adresse? Est-il possible
de faire cela sans quitter la portabilité du C standard ?

Poser une question


Peut-on
non. cela dit si tu utilises un tableau de pointeurs de fonction et une
simple boucle, modulo quelques réglages, ton compilateur devrait être en
mesure de dérouler cette boucle.
Pourriez-vous préciser votre question ? En fait, j'ai du mal à cerner ce qui
est dynamique (c'est à dire non connu à la compilation ?).
J'ai cru comprendre que vous avez un certain nombre de void f(void), et que
la fonction créée dynamiquement consiste en une sorte de script linéaire
basé sur ces fonctions de base. Si c'est ça, quel est le sens (ou l'utilité)
de "ne comporterait ni boucle, ni test, mais se contenterait d'appeler dans
l'ordre des fonctions sans argument à partir de leur adresse".
Merci
Pierre
Créer dynamiquement? Diable! Tu veux dire allouer quoi? Générer du code
machine à la volée dans un bloc de mémoire allouée et l'exécuter? Ca sent le
virus polymorphe ça...
En tout cas, rien de portable, car le langage C ne garanti pas qu'un bloc
alloué par malloc() puisse être éxécutable, ni qu'il soit correctement aligné
pour exécuter du code.
Ok. Opération classique avec un tableau de pointeurs de fonctions.
Tu peux ecrire le code 'déroulé'...
af[0]();
af[1]();
af[2]();
Certains compilateurs le font tout seul...
--
-ed- [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-reference: http://www.dinkumware.com/manuals/r...px?lib=cpp
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/
"Emmanuel Delahaye"
Pas forcément. Ca a des applications perverses certes, mais sinon ce type de
génération automatique d'extensions à un algorithme est très utile en IA, et
pour des raisons de performances gagnerait à être descendu dans un langage
d'implémentation efficace tel que C.
Je crois aussi que descendre au niveau du code machine est strictement non
portable (ce qui n'est pas forcément un problème dans le contexte étudié) et
techniquement très complexe effectivement pour les raisons de droits
d'exécution. On se rapproche des techniques de debugging. Mais j'ai déjà
personnellement réussi à écrire (avec une couche ASM certes) un loader
intra-application pour un exécutable 32bits, et ceci dans un contexte
Windows 3/ Microsoft C 16bits (en 1991). Donc c'est très complexe, mais
possible (le relogement des pointeurs internes du code peut lui être
particulièrement complexe).
J'avais aussi étudié un problème plus simple consistant à invoquer une
fonction existante, mais avec un jeu d'arguments défini au runtime, c'est à
dire en construisant dynamiquement la stackframe. En utilisant en plus une
fonction de type "stdarg", on peut imaginer des possibilités très ouvertes.
Une autre solution plus simple est de générer le code C d'une librairie
dynamique sur mesure, de la compiler à la volée, de la charger et d'invoquer
la fonction contenue. Heureusement de nos jours les librairies (réellement)
dynamiques sont devenues une fonctionnalité assez courante.
J'ai lancé récemment ici-même un thread sur un tel sujet, dont le titre
initial portait sur la "portabilité conceptuelle des fonctions naked". Voir
dans l'archive du forum.
Cordialement,
--
============================= "Il vaut mieux avoir un gros nez que deux petits"
"Qui pisse loin ménage ses chaussures"
"Noël au balcon, enrhumé comme un con"
"C'est au pied du mur qu'on voit mieux le mur"
"Pingouins dans les champs, hiver méchant"
Proverbes du terroir
Patrick "Zener" BRUNET @ ZenerTopia
Cybernétique & Génie Logiciel
http://zener131.free.fr/ContactMe