Pregunta

Mi experiencia previa es C/C++/C#.

Estoy usando una biblioteca C++ en un proyecto xcode (para ser específicos, la biblioteca es PJSIP).Para usar la biblioteca tengo que conectar un par de devoluciones de llamada a mi código de esta manera:

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

Quiero cambiar esta sintaxis de C++ a Objective C

Así que lo hice:

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

Intenté buscar delegado en Objective C pero no pude encontrar un caso similar en el que la devolución de llamada ya esté implementada en C++ y desee usarla con la sintaxis de Objective-C.

Gracias

¿Fue útil?

Solución

En primer lugar, no es necesario convertir nada en absoluto.Está perfectamente bien llamar a bibliotecas C++ desde Objective-C.

En segundo lugar, lo que está causando el error del compilador es que estás intentando colocar un método en un lugar donde debería haber un puntero de función.No se puede crear un puntero de función a partir de un método Objective-C utilizando el & Operador.Simplemente mantén tu on_reg_state() funcione y úselo como lo hizo antes, así es como también realiza devoluciones de llamada en los marcos basados ​​en C de Apple (que necesitará tan pronto como vaya más allá de lo que proporcionan las API de Objective-C de alto nivel).

Y en tercer lugar, tu + (void)Init El método parece un poco extraño.Le desaconsejaría encarecidamente que escribiera un método llamado Init (en mayúscula).Si tiene la intención de escribir un inicializador, debería ser - (id)init, es decir.minúsculas y regresando id.Y no olvide llamar al inicializador designado de su superclase, verificar su valor de retorno, asignarlo a uno mismo y devolverlo al final del init método (ver Implementación de un inicializador en documentación de Apple si no estás familiarizado con eso).Y si su método no es un inicializador, use un nombre diferente, por ejemplo. - (void)createConfig.

Otros consejos

En este caso, desea usar selectores.

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

 }
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top