Объявление функции обратного вызова внутри FSEventStreamCreate - PullRequest
2 голосов
/ 11 сентября 2011

Есть несколько примеров использования FSEvent для прослушивания изменений в файловой системе.

Как прослушать изменения файловой системы MAC - kFSEventStreamCreateFlagWatchRoot

и

FSEvents странность на OS X Leopard

При создании события с FSEventStreamCreate кажется, что все они прекрасно проходят элемент обратного вызова.Нет параметров или чего-то еще, просто &feCallbackПо сути, кажется, что они передают переменную, а не функцию, если это имеет смысл.

Но я получаю ошибку Use of Undeclared identifier, когда пытаюсь это сделать.Что дает?

 FSEventStreamRef stream = FSEventStreamCreate(NULL, 
                                                  &feCallback, // what does '&' mean? Why are no parameters passed?
                                                  &cntxt, 
                                                  pathsToWatch, 
                                                  kFSEventStreamEventIdSinceNow, 
                                                  1,
                                                  kFSEventStreamCreateFlagWatchRoot );

, а затем, позже, будет иметь функцию обратного вызова:

static void feCallback(ConstFSEventStreamRef streamRef,
                       void* pClientCallBackInfo,
                       size_t numEvents,
                       void* pEventPaths,
                       const FSEventStreamEventFlags eventFlags[],
                       const FSEventStreamEventId eventIds[]) 
{
        NSLog(@"The file changed!"); 
}

Мне бы хотелось, чтобы какой-нибудь пример кода помог получить работающему объекту с открытым исходным кодом: https://bitbucket.org/boredzo/fs-notifier/overview

Но то же самое.У него есть метод:

- (id) initWithCallback:(FSEventStreamCallback)newCallback path:(NSString *)newPath;

, и я не могу передать его newCallback из-за ошибки, описанной выше.

1 Ответ

2 голосов
/ 11 сентября 2011

При создании события с FSEventStreamCreate кажется, что все они прекрасно проходят элемент обратного вызова.Никаких параметров или чего-либо еще, просто &feCallback.

FSEventStreamRef stream = FSEventStreamCreate(NULL, 
                                                 &feCallback, // what does '&' mean? Why are no parameters passed?

& является оператором «адреса» и вычисляет указатель на его операнд.В этом нет необходимости;имя функции, отсутствующее в вызове функции, всегда оценивается как указатель на функцию, с &.

или без него. Таким образом, передается указатель на функцию feCallback, которая будет вызывать объект FSEventStreamэто обратно.

В основном кажется, что они передают переменную, а не функцию, если это имеет смысл.

Это имеет смысл, но нет,это не правильно.Они передают саму функцию.

Можно объявить переменную, которая содержит указатель на функцию.Если бы feCallback была такой переменной, то feCallback и &feCallback означали бы разные вещи: feCallback был бы указателем на функцию (внутри переменной feCallback), тогда как &feCallback был бы указателем напеременная.

В вашем случае, хотя feCallback является функцией, оба выражения эквивалентны;в любом случае передается указатель на функцию.

Но при попытке сделать это я получаю сообщение об ошибке «Необъявленный идентификатор».Что дает?

Вы не объявили этот идентификатор (в данном случае, эту функцию).

, а затем имеете функцию обратного вызова:

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

Причина в том, что компилятор не знает, что такое «feCallback», пока вы не скажете ему, что и является объявлениемделает.Когда вы пытаетесь сослаться на «feCallback» перед его объявлением или определением, компилятор не знает, о чем вы говорите.

Другим способом было бы переместить определение функции вверх.Определение считается декларацией для всего, что следует за ним.Я бы оставил определение там, где оно есть, и просто добавил объявление в верхней части файла.

В любом случае, компилятор будет знать, что такое feCallback, когда вы передадите его * 1053.*.

...