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 :

connaitre l'appelant d'une fonction


Sujet :

C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 36
    Par défaut connaitre l'appelant d'une fonction
    Bonjour,
    J'ai redéfinit la méthode fwrite.
    Dans la nouvelle fonction fwrite, je voudrais effectuer un traitement différent selon l'appelant. Est-il possible de savoir qui appelle fwrite sans en changer le prototype. Je voudrais en gros savoir d'où a été appelé ma fonction.
    L'appel se fait depuis un code C qui appelle le fwrite d'une dll en c++.
    Merci

  2. #2
    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
    Par défaut
    Est-il possible de savoir qui appelle fwrite
    Non.

  3. #3
    Membre chevronné
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    258
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 258
    Par défaut
    On peut, en faisant appel aux fonctions de profiling du compilateur. Avec les outils GNU, voir là : http://www-128.ibm.com/developerwork...ry/l-graphvis/

    Ton code va par contre devenir beaucoup plus lent, puisque le compilateur ajoute des instructions au début et à la fin de chaque fonction. Pourquoi exactement veux-tu faire une chose pareille ?

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 36
    Par défaut
    Merci,
    Je vais lire cette doc.
    J'en ai besoin car je dois faire un traitement spécifique (conversion big endian/little endian) ou pas, avant le fwrite selon le programme qui appelle. Le problème est que je ne peut pas modifier le code appelant. Je veut donc faire cette opération dans le code appelé

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    135
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 135
    Par défaut
    C'est tout à fait possible :/ .... du moins avec vc++ (jamais essayé avec d'autres) suffit de redéfinir une fonction qui prend pour paramètre une chaine de caractères...et utiliser les macros __FUNCTION__ __LINE__ et __FILE__ (a priori, c'est __FUNCTION__ qui t'interesse il me semble..)
    Pour mon gestionaire de mémoire par exemple j'ai :

    #define new(sz) c_malloc( sz , __FILE__,__LINE__,__FUNCTION__ )
    #define delete(ptr) c_free(ptr)

    #define malloc(sz) c_malloc( sz , __FILE__,__LINE__,__FUNCTION__ )
    #define free(ptr) c_free(ptr)

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Attention: pour cela, il faut pouvoir au moins recompiler le code appelant.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 36
    Par défaut
    Merci beaucoup,
    Je pense que cela devrait résoudre mon problème. je peut effectivement recompiler le code source mais pas le modifier. J'ai juste accès à un fichier .h inclut dans l'application . Donc je devrais pouvoir redéfinir ma fonction fwrite.
    Encore merci

  8. #8
    Membre chevronné
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    258
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 258
    Par défaut
    Icareo :
    utiliser les macros __FUNCTION__ __LINE__ et __FILE__
    __LINE__ et __FILE__ sont disponibles sous VC++ et gcc (et il me semble sont standards), __FUNCTION__ est spécifique à VC++. Sous gcc, l'équivalent est __PRETTY_FUNCTION__.

    mnaulet:
    conversion big endian/little endian
    L'idée d'instrumenter le code est un pis-aller : la taille du code et sa vitesse d'exécution peuvent augmenter de façon énorme, méfie toi. Si je comprends bien, on te fournit soit du little endian, soit du big endian, et tu veux convertir dans un des deux avant le fwrite. Si tu n'as aucune info sur tes données, il va falloir passer par un gros hack. Si tes données ont une structure précise, genre un entête, tu peux peut être essayer de déterminer leur endianness.

  9. #9
    Membre confirmé Avatar de b Oo
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 179
    Par défaut
    Citation Envoyé par roulious
    On peut, en faisant appel aux fonctions de profiling du compilateur. Avec les outils GNU, voir là : http://www-128.ibm.com/developerwork...ry/l-graphvis/
    Salut roulious,
    merci beaucoup pour le lien. Je vais pouvoir regarder les méthodes appelées, et débugger plus rapidement, ...

  10. #10
    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
    Par défaut
    Il serait bon de ne pas utiliser des hacks ignobles pour pallier à tes problèmes de conception.

  11. #11
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    L'approche ne me parait pas bonne.
    Généralement, on suppose que ce qui transite au niveau des interfaces socket ou fichier sera toujours dans un même alignement. Typiquement le network byte order qui correspond à du big endian si mes souvenirs sont bons.
    Du coup, au niveau des interfaces, tu appliques des fonctions de convertion dont le corps est fonction de l'architecture sur laquelle tu tournes -> ntohl & cie.
    Et dans ton programme, tu manipuleras les données natives C++.

    PS: oublie les hack GCC avec des dll en C++.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  12. #12
    Membre chevronné
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    258
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 258
    Par défaut
    Généralement, on suppose que ce qui transite au niveau des interfaces socket ou fichier sera toujours dans un même alignement.
    Pas forcément. Dans certains formats de fichiers, on peut spécifier explicitement big/little endian. Tant qu'on ne sait pas ce que l'OP veut faire exactement, on nage un peu dans les suppositions.

  13. #13
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    Ca ne change rien. Pour un fichier particulier, on a une fonction de sérialization particulière qui va réaliser la convertion qui va bien pour la plateforme courante.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  14. #14
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    Le problème posé témoigne en effet d'une "faute" de conception.
    Si veux faire un bidouillage, tu peux toujours faire une enum, dont chaque "composante" correspondra à un appelant. L'important est-il vraiment le _nom_ de l'appelant ou bien simplement le comportement qui diffère juste selon qui appelle. Car si le nom n'est pas important, alors l'enum suffit. Et donc tu passes une composante de l'enum en argument et voila.
    C'est pas très propre, mais le fait de vouloir connaitre l'appelant c'est un peu comme le fait de vouloir connaitre le type d'un objet dans un cadre polymorphique.

  15. #15
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 36
    Par défaut
    Citation Envoyé par Alp
    Le problème posé témoigne en effet d'une "faute" de conception.
    Si veux faire un bidouillage, tu peux toujours faire une enum, dont chaque "composante" correspondra à un appelant. L'important est-il vraiment le _nom_ de l'appelant ou bien simplement le comportement qui diffère juste selon qui appelle. Car si le nom n'est pas important, alors l'enum suffit. Et donc tu passes une composante de l'enum en argument et voila.
    C'est pas très propre, mais le fait de vouloir connaitre l'appelant c'est un peu comme le fait de vouloir connaitre le type d'un objet dans un cadre polymorphique.
    Ce n'est pas un problème de conception. Le but du projet est d'exécuter des sources existantes sur un terminal et codées en C sur un PC. J'ai donc réalisé une Dll en C/C++. Le problème est qu'il existe deux types de terminaux et que pour certaines données, lorsque j'appelle fwrite, je dois passer en little/big endian. Je reçoit des données en big endian depuis un modem et le PC travaille avec des little endian. Ces données étant stockées dans un buffer, passé en paramètre de fwrite, et qui peut contenir des entiers char ou long à la suite.

  16. #16
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    La modification doit donc se faire AVANT le fwrite, car le fwrite ne peut PAS savoir où commence un nombre et où en finit un autre (surtout s'il y a aussi dans les données des chaînes de caractères, des short, etc.).

    Donc, il va falloir modifier les sources existantes pourqu'elles fassent appel à htons()/htonl() avant la sauvegarde et ntohs()/ntohl() après le chargement...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  17. #17
    Membre chevronné Avatar de Flo.
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2002
    Messages : 379
    Par défaut
    Salut,

    je suis peut-être à coté de la plaque (tant ma solution me parait simple ... ), donc désolé par avance.

    Pourquoi ne pas ajouter simplement un argument supplémentaire à ta fonction, une string par exemple ? Ainsi chaque appelant pourrait passer par cette string son propre nom.

    Dans nos projets on utilise souvent cette astuce pour faire du log d'erreurs.

    Exemples:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    // le prototype de la fonction fwrite 
    void fwrite(arg1, arg2, ... , string userFunction);
    on aurait ensuite, par exemple, 2 fonctions :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void toto()
    {
         fwrite(value1, value2, ... , "toto");
    }
     
    void tata()
    {
         fwrite(value1, value2, ... , "tata");
    }
    et ainsi la fonction fwrite peut connaitre son appelant.

    Et encore désolé si je suis dans les choux

    Flo.

  18. #18
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Tu y es.
    De toute manière, le problème que j'ai décrit reste entier...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  19. #19
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 36
    Par défaut
    Citation Envoyé par Flo.

    Pourquoi ne pas ajouter simplement un argument supplémentaire à ta fonction, une string par exemple ? Ainsi chaque appelant pourrait passer par cette string son propre nom.
    je ne peux pas toucher au code source en lui même. La seule chose que je peux faire est d'éventuellement utiliser des macros pour changer l'appel.
    Le but est de tester les sources sur le PC et quand elles fonctionnent les remettre sur le terminal, c'est pourquoi je ne doit pas toucher à ce code.

  20. #20
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    Tu es passé à côté d'un truc : il est parfaitement possible d'avoir une unique fonction qui décode depuis un format connu et précis vers le format natif (qu'il soit little, big, median endian, ...) de ton système. Fonction qui existe déjà. On a doné les noms de la famille de fonctions responsables de ces transformations.

    Peu importe qui appelle. L'important est de savoir dans quel format est le fichier/flux que tu manipules. Tout le reste peut devenir très rapidement transparent. Car je doute qu'il y ait un quelconque intérêt à transformer un buffer vers le format non natif.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 6
    Dernier message: 12/10/2008, 20h33
  2. Appel d'une fonction
    Par georgeabitbol dans le forum ASP
    Réponses: 4
    Dernier message: 08/07/2004, 14h29
  3. Réponses: 4
    Dernier message: 02/06/2004, 16h35
  4. Appel d'une fonction
    Par jfphan dans le forum ASP
    Réponses: 4
    Dernier message: 14/04/2004, 15h06
  5. A la recherche de l'appel d'une fonction...
    Par karl3i dans le forum C
    Réponses: 3
    Dernier message: 24/09/2003, 12h34

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