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

Langage C++ Discussion :

[Langage] pointeur de fonction membre


Sujet :

Langage C++

  1. #1
    Membre éprouvé Avatar de uriotcea
    Homme Profil pro
    Ingénieur / physicien
    Inscrit en
    Septembre 2003
    Messages
    1 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur / physicien
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 301
    Par défaut [Langage] pointeur de fonction membre
    je voudrais passer une fonction membre à une subrooutine 'C', j'ai donc fait cela:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    #ifdef __cplusplus
      extern "C" {
    #endif
      extern int my_func_C_(char *,void(*My_class_Cpp::func)(int *,int *,int *,double *));
    #ifdef __cplusplus
      } // "C"
    #endif
     
    class My_class_Cpp
    {
      void  Une_fonction();
      void my_func_membre(int *n,int *ngood,int *nstop,double *l);
      ...
    };
     
    void My_cass_Cpp::Une_fonction()
    {
       my_func_C_("toto",&My_class_Cpp::my_func_membre);
     }

    Ca compile et ca link, ca fonctionne mais les variable n, ngood..., valent n'importe quoi.
    La question que je me pose est que dans le code 'C' le prototype de la fonction est déclarée comme suit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
      int my_func_C_(char *,void(*func)(int *,int *,int *,double *));
    et ne connait donc pas My_class

    enfin, si j'ai été assez clair et si vous avez une idée pour réaliser ca, merci d'avance

  2. #2
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Bonjour,
    Je n'ai pas fait le test, mais je dirais qu'à priori, côté C il te manque le pointeur sur this dans ta déclaration:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int my_func_C_(char *,void(*func)(void*this,int *,int *,int *,double *));

  3. #3
    Membre éprouvé Avatar de uriotcea
    Homme Profil pro
    Ingénieur / physicien
    Inscrit en
    Septembre 2003
    Messages
    1 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur / physicien
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 301
    Par défaut
    Que veux-tu dire par coté C
    Est-ce dans le prototype 'extern' ou est-ce dans le fichier du corp de la fonction ?

  4. #4
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Ta fonction C doit suivre cette définition (côté déclaration & définition):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int my_func_C_(char *,void*le_this, void(*func)(void*this,int *,int *,int *,double *));
    Et ensuite l'appel:

  5. #5
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 401
    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 401
    Par défaut
    Ça passera peut-être sous gcc, mais pas si facilement sous Visual:
    Sous Visual, les fonctions membres de classe C++ utilisent par défaut la convention d'appel thiscall, alors que les fonctions C utilisent la convention d'appel __cdecl...

    Par contre, si tu déclares explicitement ta fonction membre __cdecl, ça peut marcher.
    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.

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 401
    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 401
    Par défaut
    Un truc de ce genre pourrait bien marcher sous Visual:
    Code C/C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    #ifndef H_MY_FUNC_C_20081030_1413
    #define H_MY_FUNC_C_20081030_1413
     
    /* my_func_c.h */
    #ifndef EXTERN_C
    	#ifdef __cplusplus
    		#define EXTERN_C extern "C" 
    	#else
    		#define EXTERN_C extern
    	#endif
    #endif
     
    #ifdef __cplusplus
    	class My_class_Cpp;
    	typedef void (__cdecl My_class_Cpp::* MYFUNCCPROC)(int*, int*, int*, double*);
    #else
    	struct My_class_Cpp;
    	typedef void (__cdecl * MYFUNCCPROC)(struct My_class_Cpp* this, int*, int*, int*, double*);
    #endif
     
    EXTERN_C int my_func_C_(char *, MYFUNCCPROC);
     
    #endif/* ! H_MY_FUNC_C_20081030_1413 */
    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
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 401
    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 401
    Par défaut
    Mais as-tu vraiment besoin d'un pointeur de fonction membre ?
    Ne peux-tu pas tout simplement passer un pointeur vers un wrapper statique ?
    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.

  8. #8
    Membre éprouvé Avatar de uriotcea
    Homme Profil pro
    Ingénieur / physicien
    Inscrit en
    Septembre 2003
    Messages
    1 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur / physicien
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 301
    Par défaut
    OUi actuellement j'utilise un membre static mais c'est pas sastisfaisant, parce que j'ai besoin d'aceder à des membres de ma class. Je vais essayé le 'wrapper'
    Sinon je suis sous gcc

  9. #9
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par uriotcea Voir le message
    Sinon je suis sous gcc
    C'est vrai ce qu'avait souligné Medinoc. Suivant la convention d'appel, le this peut être passé par registre (sous PC/Windows il me semble que c'est ecx) ou sur la pile. Il faut vérifier que les conventions d'appels seront les mêmes entre ton interface C et ton implémentation C++.

  10. #10
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 401
    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 401
    Par défaut
    La grosse inconnue ici, c'est la convention d'appel C++ de MinGW.
    Côté C, aucun problème, car deux des conventions d'appels C sont parfaitement standardisées sous Windows, et la troisième est rarement utilisée (sauf sous Borland).
    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.

  11. #11
    Membre éprouvé Avatar de uriotcea
    Homme Profil pro
    Ingénieur / physicien
    Inscrit en
    Septembre 2003
    Messages
    1 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur / physicien
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 301
    Par défaut
    Ca a l'air super compliqué ce que vous m'indiquez tous. Pouvez vous pour simplifier me dire ce que je dois modifier sur mon example de code pour que ca fonctionne. Pour rappel, je suis sous gcc et l'example fournit est bien compiable et linkable mais ne fonctionne pas correctement

  12. #12
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 401
    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 401
    Par défaut
    Si tu utilises un wrapper statique, ça devrait marcher à tous les coups.
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class My_class_Cpp
    {
      void  Une_fonction();
      void my_func_membre(int *n, int *ngood, int *nstop, double *l);
      static void my_func_statique(void *this, int *n, int *ngood, int *nstop, double *l);
    };
     
    void My_class_Cpp::my_func_statique(void *tt, int *n, int *ngood, int *nstop, double *l)
    {
      static_cast<My_class_Cpp*>(tt)->my_func_membre(n, ngood, nstop, l);
    }
    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.

  13. #13
    Membre éprouvé Avatar de uriotcea
    Homme Profil pro
    Ingénieur / physicien
    Inscrit en
    Septembre 2003
    Messages
    1 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur / physicien
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 301
    Par défaut
    Merci mais cette ligne ne passe pas la compilation

    static void my_func_statique(void *this, int *n, int *ngood, int *nstop, double *l);.

    Si je met "void *tt" à la place de "void *this" ca passe, mais evidement le code en C ne connaissant pas this...

  14. #14
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 401
    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 401
    Par défaut
    C'est corrigé. Quelque fautes de frappe et des signes de ponctuation indésirés...

    Par contre, si tu ne peux pas passer un void* (ou un intptr_t) à ta fonction C, alors elle est mal faite.
    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.

  15. #15
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par uriotcea Voir le message
    Merci mais cette ligne ne passe pas la compilation

    static void my_func_statique(void *this, int *n, int *ngood, int *nstop, double *l);.

    Si je met "void *tt" à la place de "void *this" ca passe, mais evidement le code en C ne connaissant pas this...
    T'es sûr que tu compile en C? Parce que autant this est réservé en C++ autant en C, non (enfin, pas à ma connaissance).

  16. #16
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 401
    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 401
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    T'es sûr que tu compile en C? Parce que autant this est réservé en C++ autant en C, non (enfin, pas à ma connaissance).
    Le code du wrapper statique est en C++, c'est normal.
    C'est moi qui ai confondu avec des langages comme C# où les mots-clés dépendent du contexte, et j'ai bêtement cru que this ne serait pas réservé dans une fonction statique ou non-membre...
    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 éprouvé Avatar de uriotcea
    Homme Profil pro
    Ingénieur / physicien
    Inscrit en
    Septembre 2003
    Messages
    1 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur / physicien
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 301
    Par défaut
    Autant pour moi, j'ai simplifier un peu mon probleme, mais cette fonction est aussi appelé par du fortran qui lui evidement ne connait pas this

    Sinon la ligne
    static void my_func_statique(void *this, int *n, int *ngood, int *nstop, double *l);
    ne compile toujours pas

  18. #18
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 401
    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 401
    Par défaut
    Comme tu l'as dit, remplace this par tt et ça compilera.
    Le problème, c'est surtout qu'il faut ajouter un paramètre (de type void* ou mieux, intptr_t) à my_func_C_...
    Généralement, on appelle ce paramètre "userData" ou "context"...
    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.

Discussions similaires

  1. Pointeur de fonction membre.
    Par fabone dans le forum C++
    Réponses: 2
    Dernier message: 18/01/2006, 14h18
  2. Pointeur de fonction membre
    Par legend666 dans le forum C++
    Réponses: 1
    Dernier message: 04/10/2005, 21h46
  3. Réponses: 10
    Dernier message: 03/02/2005, 14h09
  4. Réponses: 5
    Dernier message: 12/01/2005, 21h58
  5. [langage] Pointeur sur fonction
    Par Fanch.g dans le forum Langage
    Réponses: 2
    Dernier message: 02/10/2004, 11h43

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