2010-03-02 5 views
0

Je suis en train d'encapsuler une API C existante pour la rendre plus facile à utiliser dans mon programme VS2008 C++. L'API C attend un tableau de structures "TABLE_ENTRY" qui incluent un pointeur de fonction comme dans le code ci-dessous. Mais j'ai du mal à stocker un pointeur sur une fonction membre dans le pointeur de fonction. Quelqu'un peut-il signaler ce que je peux faire mal?stockage d'un pointeur sur une fonction membre

Merci, PaulH

Mon code ressemble essentiellement comme suit:

struct TABLE_ENTRY; // forward decl 

typedef int (WINAPI *MYPROC)(DWORD msg, TABLE_ENTRY* entry); 

struct TABLE_ENTRY { 
    const char* description; 
    DWORD value; 
    MYPROC callback; 
}; 

class MyClass 
{ 
public: 
    MyClass() : description("Some Description"), 
       some_value(1) 
    { 
    }; 

    int MyProc(DWORD msg, TABLE_ENTRY* my_entry) 
    { 
     return 0; 
    }; 

    TABLE_ENTRY* operator*() 
    { 
     entry_.description = description.c_str(); 
     entry_.value = some_value; 
     // error C2440: '=' : cannot convert from 'boost::_bi::bind_t<R,F,L>' to 'MYPROC' 
     entry_.callback = boost::bind<int>(&MyClass::MyProc, this); 
     return &entry_; 
    }; 

    TABLE_ENTRY entry_; 
    std::string description; 
    DWORD some_value; 
}; 

class MyClassCollection 
{ 
public: 
    TABLE_ENTRY* GetTable() 
    { 
     // is this okay or is it Evil & wrong? 
     return (&collection_.front())->operator*(); 
    }; 

    void Add(MyClass& my_class) 
    { 
     collection_.push_back(my_class); 
    } 
private: 
    std::vector<MyClass> collection_; 
}; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    MyClass class1; 
    MyClass class2; 

    MyClassCollection collection; 
    collection.Add(class1); 
    collection.Add(class2); 

    TABLE_ENTRY* table = collection.GetTable(); 
    TABLE_ENTRY entry1 = table[ 0 ]; // should be class1's table 
    TABLE_ENTRY entry2 = table[ 1 ]; // should be class2's table 

    return 0; 
} 
+0

au lieu de 'MYPROC', vous voulez utiliser le type' boost :: function '; –

+0

Votre utilisation de la surcharge de l'opérateur est mauvaise, d'ailleurs. – GManNickG

+0

@Johannes: et ensuite le donner à C API? –

Répondre

2

boost::bind crée un foncteur, à savoir une instance d'une classe qui implémente operator(). Ceci n'est pas interchangeable avec les pointeurs de fonction C simples.

+1

La solution n'étant pas utiliser 'boost :: bind'. Vous avez utilisé un pointeur de fonction vanilla, pas même un pointeur de fonction membre (qui nécessite une instance d'une classe à appeler.) C'est une chose malheureuse de langages statiquement typés, en particulier C (que l'API est), où nous pouvons t même utiliser des modèles pour au moins obtenir un peu plus de généralité (par exemple, avec boost :: bind). Vous devrez créer une fonction statique qui déléguera l'appel à la procédure "réelle". – GManNickG

+1

La question est, cependant, comment lier le pointeur 'this'. Le pointeur de functon statique n'a aucun moyen de savoir sur quel objet appeler. Je parie que certains des champs de cette entrée peuvent servir pour cela, par exemple: –

+0

La plupart des APIs de rappel C ont une notion de * fermeture * ou de * données privées * pour revenir, disons, à structurer un périphérique spécifique dans un pilote de périphérique. Je me demande à quoi sert ce champ 'description' ... –

1

Ce:

typedef int (WINAPI *MYPROC)(DWORD msg, TABLE_ENTRY* entry); 

... doit être le suivant:

typedef int (WINAPI MyClass::*MYPROC)(DWORD msg, TABLE_ENTRY* entry); 

Il y avait un tas d'autres problèmes, mais je pense que ce que vous demandiez était votre pointeur de fonction membre , donc je n'ai pas besoin de commenter le reste.

+0

Eh bien, ce que l'OP veut évidemment, c'est de convertir le précédent en le dernier en "liant" le paramètre "this". – AnT

+0

@AndreyT: Vous avez peut-être raison, mais ce n'est pas comme ça que j'ai lu l'OP. J'ai déduit du titre du post que le problème stockait un pointeur vers une fonction membre, et PaulH utilisait simplement bind pour atteindre cet objectif. Pas une question à propos de lier autant qu'une question sur les pointeurs de la fonction membre. Mais encore une fois, vous pourriez avoir raison. –

Questions connexes