передача функции в качестве параметра - PullRequest
4 голосов
/ 12 августа 2011
void dispatch_for(dispatch_queue_t *queue, long number, void (* work)(long)){
    int loop = number;
    int i;
    task_t *ctask;
    for(i = 0; i<loop;i++){
        ctask = create_task((void *)work,number,"for_test");
        dispatch_async(queue,ctask);
    }
}    

task_t *task_create(void (* work)(void *), void *param, char* name){

    //do something
}

Я получаю работу как функцию, и мне нужно передать ее в функцию create_task .. (1-й параметр)
Как мне пройти?

Ответы [ 5 ]

4 голосов
/ 12 августа 2011

имя функции без скобок является указателем на эту функцию:

void work(void) {
...;
}

void main(void) {
task_create(work, void, void);
}
1 голос
/ 12 августа 2011

Функция work не имеет одинаковую подпись в dispatch_for и task_create (аргумент - указатель в одном, длинный в другом)

Кажется странным, что вы хотите использовать одну и ту же функцию в обоих случаях

1 голос
/ 12 августа 2011

Самое простое - это определение типа для требуемого типа функции.Так что вы можете сделать

typedef void workfunc_t(void *);

workfunc_t sample_workfunc; // in order to ensure type-correctness

void workfunc_t(void *)
{
    // ...
}

void dispatch_for(dispatch_queue_t *queue, long number, workfunc_t * work)
{
    int loop = number;
    int i;
    task_t *ctask;
    for(i = 0; i<loop;i++) {
        ctask = create_task(work, number, "for_test");
        dispatch_async(queue,ctask);
    }
}

task_t *task_create(workfunc_t work, void *param, char* name){
    //do something
}
1 голос
/ 12 августа 2011

Поскольку вы используете C, а work является типом void (*)(long), но вы хотите сделать его void (*)(void*), просто повторно приведите тип work (это можно сделать проще используя typedef)

//declare somewhere at a global level
typedef void (*task_create_func)(void*);

//at the point where you want to call task_create
task_create((task_create_func)work, PARAM1, PARM2);

В качестве альтернативы, если вы не хотите иметь дело с typedefs, вы можете просто выполнить приведение с использованием желаемого типа указателя в точке вызова следующим образом:

task_create((void (*)(void*))work, PARAM1, PARAM2); 
1 голос
/ 12 августа 2011

Просто используйте идентификатор как любой другой параметр:

dispatch_for(queue, number, work);
...