Pointant vers une fonction qui est un membre de la classe - glfw setKeycallback
Je suis en train d'écrire un glfw application, dans lequel j'ai regroupé la fonction callse dans une classe simple. Im ayant de la difficulté à mettre la clé de rappel.
Ma classe est définie comme:
class GAME
{
private:
bool running;
public:
GAME();
int execute();
void events(int, int);
int loop();
int render();
};
L'exécution de la fonction est:
int GAME::execute()
{
glfwOpenWindow(640, 320, 8, 8, 8, 8, 0, 0, GLFW_WINDOW);
glfwSetWindowTitle("Viraj");
glfwSetKeyCallback(events);
running = true;
while(glfwGetWindowParam(GLFW_OPENED))
{
glfwPollEvents();
loop();
render();
}
return 0;
}
De compiler le code suivant sur Visual Studio 2010, donne l'erreur:
error C3867: 'GAME::events': function call missing argument list; use '&GAME::events' to create a pointer to member
À l'aide de &JEU::événements donne:
error C2664: 'glfwSetKeyCallback' : cannot convert parameter 1 from 'void (__thiscall GAME::* )(int,int)' to 'GLFWkeyfun'
1> There is no context in which this conversion is possible
Vous devez vous connecter pour publier un commentaire.
Il y a une syntaxe C++ pour le pointage de membre de la classe des méthodes, mais vous ne pouvez pas passer pour un C API de style. C comprend les appels de fonction et tous les non-statique méthode de l'objet, en prenant votre
events
comme un exemple, ressemble à cette pensée dans C conditions:void events(void* this, int, int);
ce qui signifie que chaque méthode en dehors de la norme arguments obtient également unthis
pointeur silencieusement passé.Pour faire de votre
events
C compatible fairestatic void events(int, int);
. De cette façon, il suivra l'appel C sémantique, il ne sera pas besoin d'unthis
pointeur passé. Vous devez aussi vous en quelque sorte passer votre objet de ce rappel d'une autre façon (si vous avez besoin de cet objet de données dans le rappel).this
en tant qu'utilisateur de pointeur et de l'appeler dans la fonction de rappel.Les exemples de code fournis dans les autres réponses ne décrivent pas comment faire pour rediriger votre rappel à chaque objet de la fonction membre, avec éventuellement un certain nombre d'objets. Faire de votre classe singleton va limiter votre design et pas à l'échelle de plusieurs glfw windows.
La solution évolutive consiste à définir la glfw utilisateur fenêtre pointeur vers l'objet, puis l'extraire dans le rappel, et appeler la fonction membre :
Cette solution est plus court et va travailler pour un certain nombre de windows.
J'ai aussi rencontré ce problème avec un autre glfw fonction de rappel, mais je ne voulais pas annoncer ma méthode de classe comme
static
, parce que j'avais besoin d'accéder aux variables membres à l'intérieur. J'ai donc essayéstd::function
etstd::bind
pour me donner la possibilité de lier une méthode d'instance que la fonction de rappel, mais malheureusement ce n'est pas une option lorsque vous travaillez avec C rappels.La réponse à ce problème est également indiqué dans le GLFW FAQ "Comment puis-je utiliser des méthodes C++ comme des callbacks":
Cependant, cela m'a encouragé à appliquer le pattern Singleton pour ma classe de rappel et de l'intégrer comme suit:
C'est à quoi il ressemble:
et dans mon main.cpp:
delete
pour supprimer le constructeur de copie et l'opérateur d'affectation.J'ai eu le même problème et après la lecture de ce thread, je suis venu avec une solution similaire. Je pense que c'est un peu plus propre de cette façon. Il est basé sur la fonction statique, mais elle est imbriquée à l'intérieur de la classe où nous avons mis toutes choses.
En-tête ressemble à ceci:
Et le code source:
Inspiré par N0vember réponse, je vous présente encore plus générique et dynamique de la solution:
Dans le fichier d'en-tête faire les événements(int, int) à une méthode statique. Qui a résolu le problème pour moi.
C'est une discussion utile sur les solutions possibles qui m'ont aidé avec le même problème, et je vais ajouter ma solution au cas où il s'avère utile.
Énoncé Du Problème
Mon scénario est plus générale que celles adressées par BIC, L. Senionis, et N0vember. En particulier, mon cas d'utilisation nécessite:
Proposé L'Utilisation Des Solutions
Le simple de conception singleton n'est plus de résoudre le problème. Au lieu de cela, je vais vous donner une
GLFWResponder
super-classe qui gère l'ensemble de l'installation de la complexité. Pour utiliser la classe et l'attacher réponse à une fenêtre, ici est ce qui est nécessaire.Solution Proposée De La Mise En Œuvre
Voici le sketch de la
GLFWResponder
mise en œuvre, pleinement fonctionnelle, mais avec quelques tâches. Il peut y avoir des implications sur la performance, dont je n'ai pas encore étudié.