Dir*_*lik 6 openssl block objective-c callback ios
有一个简单的一次性任务,需要一个进度条.OpenSSL有一个有用的回调,可用于此:
rsa=RSA_generate_key(bits,RSA_F4,progressCallback,NULL);
Run Code Online (Sandbox Code Playgroud)
同
static void callback(int p, int n, void *arg) {
.. stuff
Run Code Online (Sandbox Code Playgroud)
但是我想从ObjectiveC中调用它而不需要太多麻烦:
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];
}];
Run Code Online (Sandbox Code Playgroud)
使用Genrec:作为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();
}
Run Code Online (Sandbox Code Playgroud)
现在completionCallback(); 工作得非常出色,如预期的那样.但我得到一个编译器警告/错误,我无法平息进度回调:
Passing 'void (^__strong)(int, int, void *)' to parameter of incompatible type 'void (*)(int, int, void *)'
Run Code Online (Sandbox Code Playgroud)
所以很好奇 - 这样做的恰当方法是什么?
谢谢,
DW.
所有代码只需输入此答案,在使用前请仔细测试!
函数指针和块不是一回事; 前者只是对代码的引用,后者是包含代码和环境的闭包; 它们并非简单可互换.
你当然可以在Objective-C中使用函数指针,这是你的第一个选择.
如果你想使用块,那么你需要找到一种方法来包装块并将其作为函数引用传递...
定义RSA_generate_key是:
RSA *RSA_generate_key(int num,
unsigned long e,
void (*callback)(int,int,void *),
void *cb_arg);
Run Code Online (Sandbox Code Playgroud)
第四个参数可以是任何东西,并作为第三个参数传递给回调; 这表明我们可以传递块以及指向调用它的C函数的指针:
typedef void (^BlockCallback)(int,int);
static void callback(int p, int n, void *anon)
{
BlockCallback theBlock = (BlockCallback)anon; // cast the void * back to a block
theBlock(p, n); // and call the block
}
- (void) genReq:(BlockCallback)progressCallback
completionCallback:(void (^)())completionCallback
{
.....
// pass the C wrapper as the function pointer and the block as the callback argument
rsa = RSA_generate_key(bits, RSA_F4, callback, (void *)progressCallback);
assert(EVP_PKEY_assign_RSA(pkey,rsa));
rsa = NULL;
....
completionCallback();
}
Run Code Online (Sandbox Code Playgroud)
并调用:
[self genReq:^(int p, int n)
{
hud.progress = --heuristic to guess where we are --
}
completionCallback:^{
[MBProgressHUD hideHUDForView:self.view animated:YES];
}
];
Run Code Online (Sandbox Code Playgroud)
您是否需要任何桥梁演员(ARC)作为练习!
| 归档时间: |
|
| 查看次数: |
997 次 |
| 最近记录: |