аргументы функции соответствия скандиров - PullRequest
1 голос
/ 15 июля 2011

Я использую scandir для сопоставления определенных файлов из каталога.Функция соответствия принимает аргумент const struct dirent *dp.

Но мне также нужно передать еще один аргумент.Когда я пытаюсь это сделать, компиляция выдает мне предупреждение (не об ошибке), что моя функция соответствия имеет несовместимый тип указателя.

Разрешено ли передавать другой аргумент в функцию соответствия?Если это не так, мне, возможно, придется сделать эту конкретную переменную глобальной, которую я не хочу делать.

фрагмент кода:

/* below I am adding new argument - char *str */
match_function (const struct dirent *dp, char *str) {
}

function() {
count = scandir(PATH, &namelist, match_function, alphasort);
}

предупреждение:

warning: passing argument 3 of 'scandir' from incompatible pointer type

Ответы [ 4 ]

2 голосов
/ 15 июля 2011

Чтобы явно ответить на ваш вопрос

Разрешено ли передавать другой аргумент для соответствия функции?

Нет.Автор scandir() указал, какой тип функции match он ожидает;как пользователь scandir() вы должны следовать этой спецификации или написать свой собственный scandir() -эквивалент, который делает все так, как вы хотите, как предложено R .. .

2 голосов
/ 15 июля 2011

Другой подход, который может быть предпочтительнее использования глобальных переменных или данных, относящихся к потоку, состоит в том, чтобы просто написать собственную замену для scandir и получить дополнительный аргумент void *, который будет передан функции соответствия. Учитывая, что scandir легко реализуется менее чем в 50 строках кода, это вполне разумно.

Вот возможная реализация scandir:

http://git.etalabs.net/cgi-bin/gitweb.cgi?p=musl;a=blob;f=src/dirent/scandir.c

1 голос
/ 15 июля 2011

Единственный переносимый и потокобезопасный способ сделать то, что вы хотите, это использовать данные, специфичные для потока POSIX.

static pthread_key_t key;
static pthread_once_t init = PTHREAD_ONCE_INIT;
static void initfunc()
{
    int r = pthread_key_create(&key);
    assert(r==0);
}

match_function (const struct dirent *dp)
{
    char *str = pthread_getspecific(key);
    /* ... */
}

function() {
    pthread_once(&init, initfunc);
    pthread_setspecific(key, str);
    count = scandir(PATH, &namelist, match_function, alphasort);
}

Если вас не волнует безопасность потоков, вы можете просто использовать глобальную переменную для str и сделать ее намного проще.

1 голос
/ 15 июля 2011

Подумайте об этом: как бы вы передали ему дополнительный параметр? Вероятно, вы ищете замыкание, которое пока не поддерживается стандартом C, хотя gcc, по-видимому, может делать это с помощью вложенных функций .

...