Domanda

La mia esperienza di fondo è C/C ++/C#.

Sto usando una libreria C ++ in un progetto Xcode (per essere specifico la libreria è PJSIP). Per usare la libreria devo collegare un paio di callback sul mio codice come questo:

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;
 }

Voglio cambiare questo Sytnax C ++ all'obiettivo C

così ho fatto:

 +(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
 }

Ho provato a cercare il delegato in Objective C ma non sono riuscito a trovare un caso simile in cui il callback è già implementato in C ++ e si desidera usarlo con la sintassi di Objective-C.

Grazie

È stato utile?

Soluzione

Prima di tutto, non c'è assolutamente bisogno di convertire nulla. Va perfettamente bene chiamare le librerie C ++ da Objective-C.

In secondo luogo, ciò che causa l'errore del compilatore è che stai cercando di attaccare un metodo in un luogo in cui dovrebbe esserci un puntatore della funzione. Non è possibile eseguire un puntatore di funzione da un metodo Objective-C usando il & Operatore. Tieni semplicemente il tuo on_reg_state() Funzionalo e usalo come hai fatto prima, ecco anche i callback nei quadri basati su C di Apple (di cui avrai bisogno non appena vai oltre ciò che forniscono le API Objective-C di alto livello).

E in terzo luogo, il tuo + (void)Init Il metodo sembra un po 'strano. Ti scoraggerei fortemente a scrivere un metodo chiamato Init (capitalizzato). Se hai intenzione di scrivere un inizializzatore, dovrebbe essere - (id)init, cioè minuscolo e ritorno id. E non dimenticare di chiamare l'inizializzatore designato della sua superclasse, controlla il suo valore di ritorno, assegnarlo a sé e restituirlo alla fine del init Metodo (vedi Implementazione di un inizializzatore in Documentazione di Apple Se non ne hai familiarità). E se il tuo metodo non è un inizializzatore, usa un nome diverso, ad esempio - (void)createConfig.

Altri suggerimenti

In questo caso vorresti usare i selettori.

+(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]

 }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top