Convertir un callback c++ en selector objective-c
tbop
Membre
Bonjour à tous !
Ma question est finalement assez simple à résumer et pourtant je peine à trouver une réponse claire.
Voilà , j'ai un UISlider que je veux faire communiquer avec une API C++ déjà implémentée. Je voudrais faire la translation entre l'événement valuechanged déclenché par l'UISlider qui va le transmettre à l'événement valuechanged géré par le Slider de l'API C++.
J'ai donc trouvé cette méthode qui est hérité de UIControl :
http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIControl_Class/Reference/Reference.html#//apple_ref/occ/instm/UIControl/addTarget:action:forControlEvents:
Cette méthode me permettrait d'appeler automatiquement une methode de ma class UICustomSlider (par exemple -(void) onValueChanged)
onValueChanged déclencherait alors un callback inclu dans ma class.
Or voilà comment je peux rajouter ce callback c++ à ma class objective-c ?
Est-ce que cette méthode vous semble correcte ?
Merci beaucoup !
Ma question est finalement assez simple à résumer et pourtant je peine à trouver une réponse claire.
Voilà , j'ai un UISlider que je veux faire communiquer avec une API C++ déjà implémentée. Je voudrais faire la translation entre l'événement valuechanged déclenché par l'UISlider qui va le transmettre à l'événement valuechanged géré par le Slider de l'API C++.
J'ai donc trouvé cette méthode qui est hérité de UIControl :
http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIControl_Class/Reference/Reference.html#//apple_ref/occ/instm/UIControl/addTarget:action:forControlEvents:
Cette méthode me permettrait d'appeler automatiquement une methode de ma class UICustomSlider (par exemple -(void) onValueChanged)
onValueChanged déclencherait alors un callback inclu dans ma class.
Or voilà comment je peux rajouter ce callback c++ à ma class objective-c ?
Est-ce que cette méthode vous semble correcte ?
<br />@interface UICustomSlider : UISlider<br />{<br />void (*callbackcpp)();<br />}<br /><br />-(void) addCallback:(void*())f<br />-(void) onValueChanged<br />@end<br />
<br />@implement UICustomSlider<br />-(id) init<br />{<br /> self = [super init];<br /> SEL selecteur = @selector(onValueChanged);<br /> [self addTarget:self action:selecteur forControlEvents:UIControlValueChanged];<br />}<br /><br />-(void) addCallback:(void*())f<br />{<br /> callbackcpp = f;<br />}<br /><br />-(void) onValueChanged<br />{<br /> callbackcpp();<br />}<br />@end<br />
Merci beaucoup !
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
En C++
Les méthodes sont implémentées sous forme de pointeurs de fonctions. L'adresse de la fonction fait partie de la classe compilée.
Appeler une méthode est équivalent à un appel de fonction C.
En Objective-C
On parle de "messages" pour les appels de méthodes, parce que c'est le Runtime ObjC qui détermine dynamiquement qui va recevoir le message. En gros, chaque message possède un identifiant unique, et chaque classe une liste des identifiants auxquels elle peut répondre. Il y a une étape intermédiaire, qui apporte un peu de lenteur mais qui rend tout plus flexible.
Le fonctionnement est expliqué en détail dans le document sur le Runtime Objective-C.
Bref, on ne peut pas mélanger ObjC et C++ comme on veut. Les limites sont expliquées dans le document d'Apple sur ObjC (partie sur Objective-C++).
En gros, d'après mes souvenirs, on peut appeler des méthodes C++ depuis ObjC et vice-versa, mais c'est à peu près tout.
Maintenant, pour répondre à ta question, le plus simple est sans doute d'implémenter la partie Contrôleur du pattern M-V-C en ObjC++, et que seule la partie Modèle soit en C++.
Pour ton slider, tu implémenterais l'action comme d'habitude en ObjC:
C'est du code ObjC++, donc ton source doit porter l'extension .mm .
Par contre (bon je suis un peu encore débutant avec les mécanismes iphone), d'après toi je dois juste surcharger sliderMoved en fait et pas faire le mécanisme avec addTarget:action:forControlEvent ?
Dans ce cas, on peut lui passer un objet objective-C comme contexte, qui permettra alors d'appeler une méthode.
Exemple :
On ne surcharge rien ici. D'ailleurs, avec Cocoa, on privilégie toujours la composition à l'héritage.
Le mécanisme des Targets/Actions est trop long à expliquer ici, et par ailleurs largement expliqué dans les livres et dans les docs d'Apple; je te laisse étudier ces quelques bases, ensuite la réponse te sera évidente (la méthode addTarget:action: permet de lier les actions par le code, mais on fait plutôt ça sous Interface Builder habituellement).
C'est pour le Mac, mais c'est pareil sur iPhone.