¿Cómo pasar la function objective-c como callback a la function C?

Quiero llamar a la function ac desde el objective c y pasar la function objective c como una callback

el problema es que esta function tiene una callback como parámetro, así que tengo que pasar la function objective-c como una llamada de return a la function c

aquí está el encabezado de la function c

struct mg_context *mg_start(const struct mg_callbacks *callbacks, void *user_data, const char **configuration_options); 

aquí es donde trato de llamarlo

 - (void)serverstarted { NSLog(@"server started"); } - (IBAction)startserver:(id)sender { NSLog(@"server should start"); const char *options[] = { "document_root", "www", "listening_ports", "8080", NULL }; mg_start(serverstarted(), NULL, options); } 

He intentado varias forms de hacerlo y he buscado en la web para get una pista de cómo hacerlo, pero sin suerte

aquí está la biblioteca que incluyo en mi código

https://github.com/valenok/mongoose

Su principal problema es el primer parámetro para mg_start() , que se describe en la statement como const struct mg_callbacks *callbacks . Estás intentando pasar un puntero a una function. (En realidad, está tratando de pasar el resultado de una llamada a esa function, que está aún más lejos de la marca). Eso no es lo que dice: dice un puntero a un struct (en particular, a mg_callbacks struct).

El código de ejemplo en https://github.com/valenok/mongoose/blob/master/examples/hello.c muestra cómo configurar esta estructura. Debe crear la estructura y colocar el puntero en la function de callback dentro de ella. Luego pasas la dirección de esa estructura.

Otros problemas con su código: su function de callback en sí misma es completamente incorrecta:

 - (void)serverstarted { NSLog(@"server started"); } 

Lo que se quiere aquí es una function C declarada así: int begin_request_handler(struct mg_connection *conn) , es decir, toma como parámetro un puntero a una estructura mg_connection . Su serverstarted no solo no toma ese parámetro, ¡ni siquiera es una function C! Es un método Objective-C, un animal totalmente diferente. Su uso del término "function Objective-C" en su título y su pregunta es engañosa; C tiene funciones, Objective-C tiene methods. No se utilizará ningún objective-C en el código que escribirá aquí.

Lo que sugiero que hagas aquí es copyr el ejemplo de hello.c al principio. A continuación, modifique el contenido / nombres de las cosas lentamente y poco a poco para evolucionar a su propio código. Por supuesto, el aprendizaje de C también ayudaría, pero probablemente pueda sobrevivir simplemente copyndo cuidadosamente.

Como Matt ya lo dijo, no puede pasar un método Objective-C como callback donde se espera una function C. Los methods Objective-C son funciones especiales, en particular el receptor ("self") se pasa implícitamente como primer argumento a la function.

Por lo tanto, para usar un método Objective-C como manejador de requestes, necesita una function C (intermedia) como manejador y debe pasarse a esa function, usando el argumento user_data . La function C puede llamar al método Objective-C:

 // This is the Objective-C request handler method: - (int)beginRequest:(struct mg_connection *)conn { // Your request handler ... return 1; } // This is the intermediate C function: static int begin_request_handler(struct mg_connection *conn) { const struct mg_request_info *request_info = mg_get_request_info(conn); // Cast the "user_data" back to an instance pointer of your class: YourClass *mySelf = (__bridge YourClass *)request_info->user_data; // Call instance method: return [mySelf beginRequest:conn]; } - (IBAction)startserver:(id)sender { struct mg_callbacks callbacks; memset(&callbacks, 0, sizeof(callbacks)); callbacks.begin_request = begin_request_handler; const char *options[] = { "document_root", "www", "listening_ports", "8080", NULL }; // Pass "self" as "user_data" argument: mg_start(&callbacks, (__bridge void *)self, options); } 

Observaciones:

  • Si no utiliza ARC (recuento automático de references), puede omitir los (__bridge ...) .
  • Debe asegurarse de que la instancia de su class ("self") no se desasigne mientras el server se está ejecutando. De lo contrario, YourClass *mySelf no sería válido cuando se llame al manejador de requestes.