Вызов функции C без обязательных параметров

Я просматривал этот исходный код, предоставленный разработчиками библиотеки под названием libuv. В некоторых примерах кода они передают функцию в качестве параметра для другой функции, но ни один из необходимых параметров не передается. Как заполняются параметры? Я смотрю на функцию uv_fs_open.

Вот ссылка на источник (ищите код функции в строке 1000): nofollow">https://github.com/libuv/libuv/blob/202195c2f45ced200ccf880ff4502eee94f11ab5/src/unix/fs.c
Вот пример кода:

int main() {
    loop = uv_default_loop();

    int r = uv_fs_open(loop, &open_req, path, O_RDONLY, S_IRUSR, open_cb);

    if (r) {
         fprintf(stderr, "Error at opening file: %s.\n", 
                uv_strerror(uv_last_error(loop)));
    }  

    uv_run(loop, UV_RUN_DEFAULT);

    return 0;
}

void open_cb(uv_fs_t* req) {
    int result = req->result;

    if (result == -1) {
        fprintf(stderr, "Error at opening file: %s.\n", 
                uv_strerror(uv_last_error(loop)));
    }  

    uv_fs_req_cleanup(req);
    uv_fs_read(loop, &read_req, result, buf, sizeof(buf), -1, read_cb);
}

person rreichel    schedule 27.05.2015    source источник
comment
Вы ведь знаете, что такое указатель на функцию? Похоже, библиотека использует указатели функций для передачи функций обратного вызова.   -  person Paul R    schedule 27.05.2015
comment
uv_fs_open предоставляет параметры, когда он вызывает open_cb , который был предоставлен как параметр указателя функции.   -  person WhozCraig    schedule 27.05.2015
comment
Вы имеете в виду передачу open_cb в uv_fs_open без аргументов? Это потому, что вы не указываете там аргументы, вы только сообщаете uv_fs_open, какую функцию вызывать, чтобы она могла предоставить аргументы.   -  person Weather Vane    schedule 27.05.2015
comment
Предполагая, что у вас мало опыта работы с c (по характеру вашего вопроса), вам гораздо лучше учиться на реальных учебных материалах (книги, учебные пособия, специальные веб-сайты), чем на одном из более продвинутых фрагментов кода с открытым исходным кодом. Мир.   -  person Amit    schedule 27.05.2015
comment
@rreichel, вы удалили свой комментарий, но причина, по которой вы не видите, что uv_fs_open ничего не делает со своим аргументом cb (который был передан как open_cb), заключается в том, что он обрабатывается макросом с именем POST   -  person Weather Vane    schedule 27.05.2015
comment
Спасибо за быстрый ответ! Я знаю, что такое указатель на функцию, но я перехожу на C с фона Java, поэтому он идет медленно, и это не первое, о чем я подумал. Спасибо еще раз! @WeatherVane Я удалил его - случайно добавил комментарий слишком рано - упс.   -  person rreichel    schedule 27.05.2015
comment
Спустя 2 года и намного больше обучения CS я просто хотел поблагодарить всех вас за ваши добрые ответы - я понимаю, что это был вопрос новичка, и очень ценю полезные конструктивные ответы, которые вы все дали. Ваше здоровье!   -  person rreichel    schedule 09.05.2017


Ответы (1)


libuv использует для своих асинхронных функций шаблон под названием callback baton. Обоснование очень простое: предположим, вы хотите сделать что-то асинхронно. Таким образом, вы передаете функцию обратного вызова как указатель функции для вызова по завершении. Функции libuv выполняют свою работу асинхронно и вызывают указанную вами функцию по завершении.

Однако, если у вас есть более одного места, где вы вызываете эти функции, после вызова обратного вызова вам нужно будет указать для какого запроса вызывается обратный вызов. В этом заключается цель объекта baton. В случае кода вашего примера это переменная open_req (типа uv_fs_t).

Подробнее об операциях файловой системы libuv можно прочитать здесь.

person Venemo    schedule 27.05.2015
comment
Спасибо @Venemo! Вот краткое продолжение: где находится документация по написанию обратного вызова для соответствия типу uv_fs_cb? В документах API это не указано - person rreichel; 27.05.2015
comment
@rreichel в большинстве случаев эти обратные вызовы принимают один параметр, тип которого является указателем на объект baton. Я предлагаю вам взглянуть на книгу libuv: nikhilm.github.io/uvbook в ней также есть глава об операциях с файловой системой: nikhilm.github.io/uvbook/filesystem.html - person Venemo; 27.05.2015