Perte du pointeur d'un IBOutlet via performSelector

Michael31Michael31 Membre
22:46 modifié dans API AppKit #1
Bonjour,

Désolé pour les questions de débutants...
Après avoir réussi le fonctionnement des communications USB/HID, je bute sur un problème ennuyeux...
La fonction IOHIDDeviceGetReportCallback fait appel à  une procédure en C pour grer le retour des messages provenant du device USB concerné.
j'ai donc installé la dite routine = void Handle_IOHIDDeviceGetReportCallback(  ....) qui fonctionne correctement. Je récupére le message et je met à  jour l'affichage d'un NSTextView défini par un IBoutlet public. Pour cela, je passe le pointeur du message à  une méthode Objective-C via performSelector. La suite logique est bien effectuée ( je vois bien la trace sur le code ), pas de plantage, mais le pointeur de mon IBoutlet ( HID_CallBackReport = NSTextView) est égal à  0x0. Donc, pas de mise à  jour du NStextView.
Bizarre, car l'écriture " [HID_CallBackReport setStringValue:@sub routine HID];  " est bien effectué si je fais l'appel avant de passer la main à  la routine void Handle_IOHIDDeviceGetReportCallback(  ....).
Je dois faire une erreur grossière, mais je n'ai pas trouver la solution après moult heures passées sur internet...
Votre avis sera plus que bienvenu.

cordialement,

Michael


Réponses

  • ClicCoolClicCool Membre
    22:46 modifié #2
    Qu'apèles-tu un IBOutlet public ?

    Un IBOutlet est une variable d'instance, et à  priori privée à  l'instance. (PAS une variable de classe)

    Ceci-dit, même si tu le déclares @public il reste une variable d'instance.
    Donc suffit pas de donner le nom de la variable outlet, faut surtout s'adresser à  l'instance de la classe dont l'outlet aura été correctement renseigné (à  priori via IB).
  • Michael31Michael31 Membre
    22:46 modifié #3
    Bonsoir,

    Le fichier ci joint donne les détails utiles pour mieux comprendre le problème que je rencontre.
    J'utilise le terme "public" selon ce que j'ai compris dans la documentation Objective-C. Cela étant, l'utilisation de @public ne change rien au problème.

    merci pour votre aide,

    cordialement,

    Michael
  • mpergandmpergand Membre
    décembre 2009 modifié #4
    I2CbusCoder  *readReport = [[I2CbusCoder alloc] init];			// prepare to send the report to the routine
    


    C'est quoi ça  :o :o :o


    essaye:
    <br />[self performSelector: theSelector withObject: (void *)inReport ];
    


    [Edit]
    Ca y ai j'ai pigé  ;)

    pour appeler la méthode de ton objet I2CbusCoder tu doit utiliser la variable context:
    <br />SEL theSelector;<br />	theSelector = @selector(displayHIDcallBackreport:);				// get a signature from the routine<br />	I2CbusCoder&nbsp; *readReport = (I2CBusCoder*) inContext;			// prepare to send the report to the routine<br />	[readReport performSelector :theSelector withObject: (void *)inReport ];<br /><br />
    


    Naturellement tu dois le scpécifier au départ:
    IOHIDDeviceRegisterInputReportCallback(i2cHIDDevice, <br />		inputReportHID, <br />		 reportSize, 	Handle_IOHIDDeviceGetReportCallback, <br />		self);
    


    Et puis tu n'as pas besoin d'utiliser performSelector  ;)
  • Michael31Michael31 Membre
    22:46 modifié #5
    Bonjour,

    Merci pour ces informations.
    Les manips donnent les résultats suivants:

    Point 1:
    I2CbusCoder  *readReport = [[I2CbusCoder alloc] init]; --> code établi selon le descriptif Apple : j'applique les méthodes décrites qui permettent bien de passer le paramètre inReport de la fonction C à  la méthode Objective-C, le tout sans erreur.

    Point 2:
    [self performSelector: theSelector withObject: (void *)inReport ];

    L'utilisation de 'self' introduit une erreur de compilation : "error:'self' undeclared (first use in this function).

    Point 3
    I2CbusCoder  *readReport = (I2CBusCoder*) inContext;

    Ce code introduit deux erreurs de compilation:
    error:'I2CBusCoder' undeclared(first use in this function)
    error:syntax error before ')' token

    Je reste perplexe .... :'(

    Cordialement,

    Michael



  • mpergandmpergand Membre
    22:46 modifié #6
    Point 1:
    Tu crées une 2e instance de I2CbusCoder et donc les outlets sont tous à  nil, normal  ;)

    Point 2:
    Ca marche pas, d'où le Edit ...

    Point 3:
    Si  I2CbusCoder  *readReport = [[I2CbusCoder alloc] init];
    compile sans erreur dans ta méthode C, je vois aucune raison pour que:
    I2CbusCoder  *readReport = (I2CBusCoder*) inContext;
    pose un problème dans cette même méthode.


    Exemple simple d'appel d'une méthode C en ObjectiveC et réciproquement:
    @implementation Controller<br /><br />//static (optionnel)<br />void call(void* p)<br />{<br />	Controller* c=(Controller*) p;	// change le type de void* en Controller*<br />	<br />	[c display:@&quot;Hello&quot;];	// appel de display<br />}<br /><br />-(void) display:(NSString*) s<br />{<br />	NSLog(@&quot;%@&quot;,s);<br />}<br /><br />-(void) awakeFromNib<br />{<br />	call(self);	// appel de la fonction c call avec l&#39;instance de Controller en paramètre
    


  • Michael31Michael31 Membre
    22:46 modifié #7
    Comme nous disons entre collègues du monde des semiconducteurs : respect.
    Cela fonctionne comme espéré, sans passer par performSelector.
    Un grand merci pour l'aide et le temps passé . En particulier, pour le point 1 qui me permet de mieux comprendre le fonctionnement de Objective-C.
    Il me reste à  finaliser ce bloc en extrayant les quatre bytes pour affichage sur le GUI : passer inReport du format uint8_t  digérable en NSString.
    Je pourrais mettre une version du GUI ( une fois fonctionnel..) sur le site si cela présente de l'intérêt pour la communauté Mac.

    cordialement,

    Michael
Connectez-vous ou Inscrivez-vous pour répondre.