我在linux上使用clang。 格式化此块的正确方法是什么?
(int ^(int, char**)) (^f2b)(int, char**) = (int ^(int, char**)) ((int (*func)(int, char**)))
{
return int ^(int argc, char** argv){ func(argc, argv)};
};
我收到错误
error: type-id cannot have a name
int (^f2b)(int, char**) = (int ^(int, char**)) ((int (*func)(int, char**)))
错误下划线(* func)。
我正在尝试创建一个块,该块接受一个名为func的函数指针作为参数,并返回一个块,该块使用传递的参数调用该func。
答案 0 :(得分:2)
关键是来自Block_copy
1 的<Block.h>
函数。这会在块上放置一个块的副本,从而允许返回块。
#include <stdio.h>
#include <Block.h>
typedef int (^block_t)(int, char **);
typedef int (*func_t)(int, char **);
block_t (^createBlock)(func_t func) = ^(func_t func)
{
return Block_copy( ^(int argc, char **argv) { return func(argc, argv); } );
};
int showFirst(int argc, char *argv[])
{
printf("%s\n", argv[0]);
return argc;
}
int main(void)
{
int argc = 3;
char *argv[] = {"hello", "world", NULL};
block_t block1 = createBlock(showFirst);
int count = block1(argc, argv);
printf("count=%d\n", count);
Block_release(block1);
}
createBlock
将函数指针作为其参数,并返回带有签名int (^block)(int, char **)
的块。
showFirst
只是可以传递给createBlock
的函数的一种可能实现。它显示argv
数组中的第一个字符串,并返回argc
中的值。
main
函数从showfirst
函数创建一个块。然后它调用块,打印返回的值,并释放块。
代码的输出是:
您好
计数= 3
1 在阅读OP的答案之前我不知道<Block.h>
。
答案 1 :(得分:1)
http://thirdcog.eu/pwcblocks/帮了很多忙。
#include <stdlib.h>
#include <stdio.h>
#include <Block.h>
int fake_main(int argc, char** words)
{
printf("%s\n", (char*)words);
return argc;
}
int main(int argc, char* argv[])
{
typedef int(*main_type_func)(int, char**);
typedef int(^main_type)(int, char**);
typedef main_type(^f2b_type)(main_type_func);
f2b_type f2b = ^ (main_type_func func)
{
return Block_copy(^ (int apple, char** ban)
{
return func(apple, ban);
});
};
printf("%d\n", f2b(fake_main)(1, "words worked"));
}
这是完成我在问题中概述的目标的最低范例。
技巧是typedef。通过创建typedef来帮助简化类型签名。我建议您在接受和/或返回函数指针/块指针时使用这些。
Block_copy()将块从堆栈移动到堆中。
保存从
返回的块指针更为正确f2b(fake_main)
然后使用后调用
Block_release()
就可以了。
答案 2 :(得分:1)
您的类型语法不正确。根据您的使用情况,我猜测您声明f2b
是指向块的指针,该指针指向一个指向int
和char **
的函数的指针。返回int
,该块返回另一个带有int
和char **
的块,并返回int
。
该声明的正确语法是:
int (^(^f2b)(int (*) (int, char **)))(int, char **)
更复杂的C类型的语法通常是违反直觉的,特别是在多级函数和数组的情况下。
非常有用的cdecl.org网站支持块:declare f2b as block(pointer to function(int, pointer to pointer to char) returning int) returning block(int, pointer to pointer to char) returning int(他们说&#34;块&#34;而我说&#34;指向块&#34的指针;)
使用完整块文字语法(包括返回类型)写出的块定义将是这样的(记住要复制块以便返回它):
int (^(^f2b)(int (*) (int, char **)))(int, char **) =
^int (^(int (*func)(int, char **)))(int, char **) {
return Block_copy(^int (int argc, char **argv) {
return func(argc, argv);
});
};
在块文字中可以省略返回类型,因此它可以写成:
int (^(^f2b)(int (*) (int, char **)))(int, char **) =
^(int (*func)(int, char **)) {
return Block_copy(^(int argc, char **argv) {
return func(argc, argv);
});
};