Question

Mon expérience de base est C / C ++ / C #.

J'utilise une bibliothèque C ++ dans un projet xcode (pour être précis, la bibliothèque est PJSIP).Pour utiliser la bibliothèque, je dois câbler quelques rappels à mon code comme ceci:

SipTest.m

#include < pjsua-lib/pjsua.h >

static void on_reg_state(pjsua_acc_id acc_id)
{
    // Do work
} 

static void Init()
{
   // pjsua_config and psjua_config_default are  defined in the header file from pjsip
    pjsua_config cfg;            
    psjua_config_default(&cfg);  

    cfg.cb.on_regstate = &on_reg_state;
 }

Je souhaite basculer cette syntaxe C ++ en Objective C

c'est ce que j'ai fait:

 +(void) on_reg_state:(pjsua_acc_id) acc_id
 {
    // Do work
 } 

 +(void) Init
 {
    pjsua_config cfg;            
    psjua_config_default(&cfg);  

    cfg.cb.on_regstate = &on_reg_state; // ***** this is causing compile error
                                        // I tried [CLASS NAME on_reg_state] and i get   runtime error
 }

J'ai essayé de rechercher un délégué en Objective C mais je n'ai pas trouvé de cas similaire où le rappel est déjà implémenté en C ++ et que vous souhaitez l'utiliser avec la syntaxe Objective-C.

Merci

Était-ce utile?

La solution

Tout d'abord, il n'est absolument pas nécessaire de convertir quoi que ce soit. Il est parfaitement bien d'appeler des bibliothèques C ++ à partir d'Objective-C.

Deuxièmement, ce qui cause l'erreur du compilateur est que vous essayez de coller une méthode à un endroit où il devrait y avoir un pointeur de fonction. Vous ne pouvez pas créer un pointeur de fonction à partir d'une méthode Objective-C à l'aide de l'opérateur &. Gardez simplement votre fonction on_reg_state() et utilisez-la comme vous l'avez fait auparavant, c'est ainsi que vous effectuez également des rappels dans les frameworks basés sur C d'Apple (dont vous aurez besoin dès que vous irez au-delà de ce que fournissent les API Objective-C de haut niveau).

Et troisièmement, votre méthode + (void)Init semble un peu étrange. Je vous déconseille fortement d'écrire une méthode appelée Init (en majuscule). Si vous avez l'intention d'écrire un initialiseur, il doit être - (id)init, c'est-à-dire minuscule et renvoyer id. Et n'oubliez pas d'appeler l'initialiseur désigné de sa superclasse, de vérifier sa valeur de retour, de l'affecter à self et de le renvoyer à la fin de la méthode init (voir Implémentation d'un initialiseur dans Documentation d'Apple si vous n'êtes pas familier avec cette). Et si votre méthode n'est pas un initialiseur, utilisez un nom différent, par exemple - (void)createConfig.

Autres conseils

dans ce cas, vous voudrez utiliser des sélecteurs.

+(void) on_reg_state:(pjsua_acc_id) acc_id
 {
    // Do work
 } 

 +(void) Init
 {
    pjsua_config cfg;            
    psjua_config_default(&cfg);  

    cfg.cb.on_regstate_selector = @selector(on_reg_state:);
    cfg.cb.target = self; //Self here is the class object in your 'Init' method, which is poorly named.
    //Use this like [cfg.cb.target performSelector:cfg.cb.on_regstate_selector withObject:...etc]

 }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top