Tiene una tarea única simple que necesita una barra de progreso. OpenSSL tiene una utilidad de devolución de llamada, que se puede utilizar para ello:ObjC blocks & openssl C devoluciones de llamada
rsa=RSA_generate_key(bits,RSA_F4,progressCallback,NULL);
con
static void callback(int p, int n, void *arg) {
.. stuff
Sin embargo, quiero llamar a esto desde ObjectiveC sin demasiados preámbulos:
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.mode = MBProgressHUDModeAnnularDeterminate;
hud.labelText = @"Generating CSR";
[self genReq:^(int p,int n,void *arg) {
hud.progress = --heuristic to guess where we are --
} completionCallback:^{
[MBProgressHUD hideHUDForView:self.view animated:YES];
}];
Con Genrec : como método objC:
-(void)genReq:(void (^)(int,int,void *arg))progressCallback
completionCallback:(void (^)())completionCallback
{
.....
rsa=RSA_generate_key(bits,RSA_F4,progressCallback,NULL);
assert(EVP_PKEY_assign_RSA(pkey,rsa));
rsa=NULL;
....
completionCallback();
}
Ahora completionCallback(); funciona espléndidamente y como se esperaba Pero consigo una advertencia del compilador/error que no puedo sofocar la devolución de llamada para el progreso:
Passing 'void (^__strong)(int, int, void *)' to parameter of incompatible type 'void (*)(int, int, void *)'
Así que tengo curiosidad - ¿cuál es la manera apropiada de hacer esto?
Gracias,
Dw.
Most Lovely! Y __bridge es todo lo que se necesita para ARC. Es una pena que uno necesite tener la devolución de llamada() en el medio - es decir, que uno no puede pasar el progressCallback como un (void (*) (int, int, void *)) de su vacío (^ __ strong) (int, int, void *) directamente. –
@ Dirk-WillemvanGulik: la única forma razonable de admitir el pase automático de un bloque, es decir, el cierre (puntero de código + entorno), como un puntero de función (solo un puntero de código) sería generar dinámicamente fragmentos de código; y eso tiene varios inconvenientes. El patrón común en C es especificar un puntero de función tomando un valor extra, generalmente de tipo 'void *', que se puede usar para pasar un entorno definido por el usuario y así construir manualmente un cierre - y openssl sigue ese patrón y la solución arriba simplemente lo usa. – CRD
Clear. ¡Gracias de nuevo!).Has cavado en NSStackBlock y tiene mucho sentido. –