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

C++ Discussion :

[Insoluble] Allocation mémoire pour gen dynamique de code


Sujet :

C++

  1. #1
    Membre éclairé Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Points : 844
    Points
    844
    Par défaut [Insoluble] Allocation mémoire pour gen dynamique de code
    Voilà j'ai besoin d'appeller des fonctions d'une DLL quelconque (qui peut changer à l'exécution). Grand pb. s'il en est.

    Donc mon idée est d'allouer à l'exécution une zone mémoire exécutable
    et d'y écrire (à la brutos) les prologues & épilogues ASM (en utilisant un pointeur byte).

    En gros, je veux m'affranchir de générer du byte code dans un fichier, faire une édition de lien, lancer un autre exécutable.

    Est-ce que ma méthode est viable ? Est-ce que l'on peut faire mieux ? Est-ce que je risque des "General Protection Fault" (comment rendre mon code plus sur ?).

    Est-ce que cela posera des pbs. avec des technos plus évoluées comme C++ mangling, COM+, exceptions (C++, structurées), ... Quand est-il des calling conventions, ... ?

    A noter que j'ai sous la main une modélisation des prototypes des fonctions de la DLL (dont je connais le nb. de params, ref & value passing, types, ...).

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Points : 1 053
    Points
    1 053
    Par défaut
    Je connais très mal le sujet, mais je sais qu'il existe des fonctions toutes faites spécifiques à chaque plateforme pour appeler des dll à chaud. Il y a un ou deux tutos sur le site pour linux je crois, et pour windows ça ne doit pas être immensément difficile à trouver. Ca m'a l'air bien plus simple que ce que tu veux faire, ou alors j'ai mal compris.

  3. #3
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Il suffit de charger ta DLL ou autre dynamiquement et puis voilà...

    Sous linux ça serait dlopen/dlsym etc.

  4. #4
    Membre éclairé Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Points : 844
    Points
    844
    Par défaut
    Bon c'est surement que je n'était pas assez clair.

    Le nom de la DLL n'est connu qu'à l'exécution.
    Le nom de la fonction à appeller n'est connu qu'à l'exécution.
    Le nombre de paramètres d'appel n'est connu qu'à l'exécution.
    Le type des paramètres ...
    Le type de passage des paramètres (par valeur ou par référence) n'est connu ...
    ...

    Est-ce que vous voyez mieux le pb. maintenant ?

  5. #5
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Le nom de la DLL n'est connu qu'à l'exécution.
    Le nom de la fonction à appeller n'est connu qu'à l'exécution.
    Aucun problème.

    Le nombre de paramètres d'appel n'est connu qu'à l'exécution.
    Le type des paramètres ...
    Le type de passage des paramètres (par valeur ou par référence) n'est connu ...
    Il n'y aucune notion de type à l'execution, je vois donc mal comment tu ne peux connaître ceux-ci qu'à ce moment-là...

  6. #6
    Membre éclairé Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Points : 844
    Points
    844
    Par défaut
    Citation Envoyé par mchk0123
    A noter que j'ai sous la main une modélisation des prototypes des fonctions de la DLL (dont je connais le nb. de params, ref & value passing, types, ...).
    Pour être plus clair, à l'exécution, j'ai justement une hiérarchie d'instances de classes C++ décrivant la signature de chaque fonction.

    Effectivement il n'existe pas dans le langage C++ d'introspection. Mais j'ai recrée moi-même cette notion à l'aide d'une "cuisine" à moi.

    Donc pour en revenir à ma question : allocation mémoire & risques encourus à exécuter du code dedans.

  7. #7
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Ce qu'il te faut c'est un intérpréteur complet d'un langage de programmation.

  8. #8
    Membre éclairé Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Points : 844
    Points
    844
    Par défaut
    Bon je vais poster ma demande dans le forum ASM, j'aurais surement plus de réponses.

  9. #9
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Points : 1 053
    Points
    1 053
    Par défaut
    Citation Envoyé par mchk0123
    Pour être plus clair, à l'exécution, j'ai justement une hiérarchie d'instances de classes C++ décrivant la signature de chaque fonction.

    Effectivement il n'existe pas dans le langage C++ d'introspection. Mais j'ai recrée moi-même cette notion à l'aide d'une "cuisine" à moi.
    Mouais, t'as des interfaces et/ou des classes abstraites quoi. Je vois toujours pas en quoi ça rend ton problème non-trivial.

  10. #10
    Membre éclairé Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Points : 844
    Points
    844
    Par défaut
    Citation Envoyé par zais_ethael
    Mouais, t'as des interfaces et/ou des classes abstraites quoi. Je vois toujours pas en quoi ça rend ton problème non-trivial.
    Bon c'est surement que je n'était pas assez clair.

    Le nom de la DLL n'est connu qu'à l'exécution.
    Le nom de la fonction à appeller n'est connu qu'à l'exécution.
    Le nombre de paramètres d'appel n'est connu qu'à l'exécution.
    Le type des paramètres ...
    Le type de passage des paramètres (par valeur ou par référence) n'est connu ...
    ...

    Et puis :

    Est-ce que cela posera des pbs. avec des technos plus évoluées comme C++ mangling, COM+, exceptions (C++, structurées), ... Quand est-il des calling conventions, ... ?

  11. #11
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Je ne vois pas trop ton problème. Je vais parler avec du vocabulaire windows, mais les mêmes choses existent sous unix, juste avec d'autres noms :
    Le nom de la DLL n'est connu qu'à l'exécution.
    Pas de problèmes, LoadLibrary prend en paramètres une chaîne de caractères
    Le nom de la fonction à appeller n'est connu qu'à l'exécution.
    Pas de problèmes, GetProcAddress prend en paramètre une chaîne de caractères. Le plus difficile sera de deviner quel nom passer s'il s'agit de fonctions C++, qui donc seront manglées.
    Le nombre de paramètres d'appel n'est connu qu'à l'exécution.
    Le type des paramètres ...
    Le type de passage des paramètres (par valeur ou par référence) n'est connu ...
    En général, on cast l'adresse retournée par GetProcAddress en pointeur de fonction du bon type, et ça marche. Là, c'est moins simple. Mais je suppose que si tu peux mettre en asm sur la pile les bon paramètres, puis faire appeler directement l'adresse, ça devrait aller.

    En bref, je ne vois pas pourquoi recoder la fonction de chargement de DLL.

  12. #12
    Membre éclairé Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Points : 844
    Points
    844
    Par défaut
    Merci JolyLoic, enfin quelqu'un qui semble comprendre ce que j'essaye de faire. Je sais je suis pas trés clair dans mes explication.

    Je ne veux pas recoder ce que sait faire le C/C++ (comme le chargement de la DLL). Je suis fainéant, je vais utiliser ce que j'ai sous la main.

    Citation Envoyé par JolyLoic
    ... Là, c'est moins simple. Mais je suppose que si tu peux mettre en asm sur la pile les bon paramètres, puis faire appeler directement l'adresse, ça devrait aller.
    Justement c'est là ou est le pb. Je pensais faire comme ça ; mais ça c'est la vision simplifiée pour processeur x186. Est-ce que je ne dois pas prendre aussi en compte également toutes les dernières technologies :

    - cadres de piles
    - cadres de pointeurs (tableaux)
    - cadres de mémoire allouées
    - exceptions structurées et C++
    - thread safe
    - information de debugging
    ...

    Maitenenant peut-être que je suis trop peureux (ou ignorant du mécanisme ASM soujacent) vis à vis de la liste que je viens de citer, et qu'elle n'a aucun impact sur ce que je veux faire.

  13. #13
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Cherche libffi. Mais ca risque de dependre de ton compilateur.

  14. #14
    Membre actif
    Inscrit en
    Décembre 2003
    Messages
    272
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 272
    Points : 284
    Points
    284
    Par défaut
    Il me semble que le passage des arguments est relativement standardisé. Il faut juste pouvoir détecter les cas stdcall/thiscall/fastcall, mais ça doit se voir sur la décoration du nom de fonction.
    Il me semble que j'avais trouvé pas mal d'info ici.

  15. #15
    Membre éclairé Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Points : 844
    Points
    844
    Par défaut
    Merci beaucoup pour ces liens.

    Si jamais vous avez aussi de la documentation sur :

    - cadres de piles
    - cadres de pointeurs (tableaux)
    - cadres de mémoire allouées
    - exceptions structurées et C++
    - thread safe
    - information de debugging
    ...

    Je suis preneur (de manière générale tout ce qui explique comment est "décoré" l'ASM compilé à partir du C/C++ : compilos ciblés = VC++, Builder C++, mingw).

  16. #16
    Membre actif
    Inscrit en
    Décembre 2003
    Messages
    272
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 272
    Points : 284
    Points
    284
    Par défaut
    Citation Envoyé par mchk0123
    - cadres de piles
    - cadres de pointeurs (tableaux)
    - cadres de mémoire allouées
    Qu'est ce ?
    - exceptions structurées et C++
    - thread safe
    - information de debugging
    rien à faire de spécial :
    - seuls les gestionnaires d'exceptions (try/catch ou __try/__finally) demandent de poser des info particulières sur la pile. Un gestionnaire est installé lorsqu'on rencontre l'instruction try ou __try, mais rien de spécial n'est fait lors de l'appel d'une fonction.
    - Thread safe, c'est qu'il y a les bonnes instructions C/C++ au bons endroits, c'est indépendant de tout problème de compilation.
    - à ma connaissance, les info de debug sont posées sur la pile par la fonction elle même. Encore rien à faire pour la fonction appelante.

    Je suis preneur (de manière générale tout ce qui explique comment est "décoré" l'ASM compilé à partir du C/C++ : compilos ciblés = VC++, Builder C++, mingw).
    Sur l'inplémentation des exceptions (VC++), j'ai les 2 liens suivants :
    http://www.codeproject.com/cpp/exceptionhandler.asp
    http://www.microsoft.com/msj/0197/ex...exception.aspx
    Et je suis intéressé par une doc équivalente pour mingw.

  17. #17
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Points : 1 053
    Points
    1 053
    Par défaut
    Je doute sérieusement que ton projet nécéssite tant de complexité.
    Tu devrais peut-être t'interroger sur ta conception, il y a bien peu de choses que le bon vieux polymorphisme objet ne peut pas faire.
    C'est quoi ton projet au fait?

  18. #18
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par zais_ethael
    Je doute sérieusement que ton projet nécéssite tant de complexité.
    Tu devrais peut-être t'interroger sur ta conception, il y a bien peu de choses que le bon vieux polymorphisme objet ne peut pas faire.
    C'est quoi ton projet au fait?
    Le cas habituel pour avoir besoin de ca est quand on fait un interpreteur qui est capable de charger des lib dynamiques.

  19. #19
    Membre éclairé Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Points : 844
    Points
    844
    Par défaut
    Et oui !

    ...

    Et moi qui voulais avancer masqué ... C'est râté.

    Donc mon projet est effectivement un interpreteur d'expressions mathématiques simple avec pleins de DLLs non uniformisées de fonctions mathématiques.

    Comme je n'ai pas envie de recompiler l'interpreteur à chaque nouvelle DLLs (parce qu'il y en aura d'autres), je n'ai pas vraiment le choix.

    A moins de passer par des hacks comme intégrer (embedding) un compilateur C, ... etc.

  20. #20
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Points : 1 053
    Points
    1 053
    Par défaut
    Justement, en concevant ton applic différamment tu n'aurais pas ce genre de problème.
    Imaginons que ces fonctions aient l'allure suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int modulo(int,int);
    float exponent(float,int);
    int factorielle(int);
    Tu vas effectivement devoir jouer avec la pile pour parvenir à tes fins.
    Mais imaginons plutôt que toutes ces fonctions prennent le même argument, par exemple un vecteur d'objets A, A contenant un int pouvant prendre quelques valeurs définies dans une énumération et un void*, et renvoient toutes un objet A.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    A modulo(vector<A>);
    A exponent(vector<A>);
    A factorielle(vector<A>);
    Si tu conçois une sorte de langage dynamiquement typé, te voila avec des appels de fonction qui prennent un nombre quelconque d'arguments et renvoient une valeur.

Discussions similaires

  1. allocation mémoire pour tableau de string
    Par alaninho dans le forum C++
    Réponses: 2
    Dernier message: 09/03/2012, 14h44
  2. Réponses: 6
    Dernier message: 14/01/2012, 21h08
  3. Schéma d'allocation mémoire pour une matrice
    Par Thierry Chappuis dans le forum C
    Réponses: 6
    Dernier message: 01/05/2011, 13h21
  4. Allocation mémoire pour exécution de code généré
    Par mchk0123 dans le forum x86 32-bits / 64-bits
    Réponses: 6
    Dernier message: 06/04/2007, 16h26
  5. Réponses: 6
    Dernier message: 24/03/2006, 18h24

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