функтор как указатель на функцию
От: Graf Alex Украина http://grafalex.oberon.kiev.ua
Дата: 23.04.08 13:58
Оценка:
Тут наткнулся на проблему....

Есть функция, которая делает список файлов в указаной директории...
int scandir(const char *dir, struct dirent ***namelist,
              int(*filter)(const struct dirent *),
              int(*compar)(const struct dirent **, const struct dirent **));

Внутри этой функции вызывается коллбек-функция filter для того, что бы узнать подходит ли нам некоторый файл или нет...

Есть так же вспомогательная функция:
int fnmatch(const char *pattern, const char *string, int flags);

Первый параметр — маска файла, второй параметр — имя файла которое нужно проматчить по маске...

Задача: написать функтор, в который я бы мог положить маску, и что бы этот функтор вел себя как обычная сишная функция. Другими словами как мне пробросить маску файла в функцию fnmatch?

PS Смотрел в сторону pointer_to_binary_function, но так и не вкурил как это использовать
Re: функтор как указатель на функцию
От: Graf Alex Украина http://grafalex.oberon.kiev.ua
Дата: 23.04.08 14:01
Оценка:
В догонку...
dirent можно трактовать как имя файла... Т.е. это структура в которой есть имя файла...
Re: функтор как указатель на функцию
От: Vamp Россия  
Дата: 23.04.08 14:11
Оценка:
Непонятно. Если я правильно понял, что filter — это собственная (не библиотечная) функция, то что мешает из нее звать fnmatch с требуемыми параметрами?
Да здравствует мыло душистое и веревка пушистая.
Re: функтор как указатель на функцию
От: Bell Россия  
Дата: 23.04.08 14:23
Оценка: -1
Здравствуйте, Graf Alex, Вы писали:

Раз уж scandir ожидает указатель на функцию, то ничего не попишешь — придется передавать именно указатель на функцию
Ну а дополнительный параметр дл этой функции можно подсунуть например вот так:
struct static_fn
{
   const char* pattern_;
   static int filter(const dirent * param)
   {
      //...
      int i = fnmatch(pattern_, ...);
      //...
   }
};

//...

static_fn::pattern_ = "123";
scandir("c;\\test", ..., &static_fn::filter, ...);
Любите книгу — источник знаний (с) М.Горький
Re: функтор как указатель на функцию
От: Roman Odaisky Украина  
Дата: 23.04.08 14:39
Оценка:
Здравствуйте, Graf Alex, Вы писали:

GA>Есть функция, которая делает список файлов в указаной директории...

GA>
GA>int scandir(const char *dir, struct dirent ***namelist,
GA>              int(*filter)(const struct dirent *),
GA>              int(*compar)(const struct dirent **, const struct dirent **));

GA>

GA>Внутри этой функции вызывается коллбек-функция filter для того, что бы узнать подходит ли нам некоторый файл или нет...

Колбеки без контекста — зло. Отыщи такой вариант, в котором int (*filter)(struct dirent const *, void* context).

GA>Задача: написать функтор, в который я бы мог положить маску, и что бы этот функтор вел себя как обычная сишная функция. Другими словами как мне пробросить маску файла в функцию fnmatch?


Или с помощью шаблонов, или с помощью глобальных переменных.

GA>PS Смотрел в сторону pointer_to_binary_function, но так и не вкурил как это использовать :( :???:


Это из другой оперы ария.
До последнего не верил в пирамиду Лебедева.
Re: функтор как указатель на функцию
От: . Великобритания  
Дата: 23.04.08 14:41
Оценка:
Graf Alex wrote:


> Задача: написать функтор, в который я бы мог положить маску, и что бы

> этот функтор вел себя как обычная сишная функция. Другими словами как
> мне пробросить маску файла в функцию fnmatch?
А никак.
Только если глобальные переменные, либо ассемблерные хаки.
Или возможно есть что-нибудь в dirent, что позволяет протащить параметр?
И вообще, пнуть больно писателя такой функции, чтобы параметр можно было протаскивать, либо самому переписать.
Posted via RSDN NNTP Server 2.1 beta
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re: функтор как указатель на функцию
От: Кодт Россия  
Дата: 23.04.08 14:53
Оценка: 2 (1)
Здравствуйте, Graf Alex, Вы писали:

<>
scandir — это пример ошибки в дизайне. Как, кстати, и некоторые другие POSIX-овые функции.
Хороший дизайн функции с колбеками предполагает передачу пользовательского параметра.
Здесь же этого нет.

GA>PS Смотрел в сторону pointer_to_binary_function, но так и не вкурил как это использовать


Его — никак. Это С++ный шаблон, превращающий двухаргументную функцию в объект класса, унаследованного от std::binary_function (это нужно для вывода типов).

Тебе же нужна JIT-компиляция переходника, превращающего замыкание функции на первый аргумент в обычную функцию.

Можешь вдохновиться примером ATL CStdCallThunk (файл <atlstdthunk.h> из ATL7+).
Правда, придётся доработать их паяльником, т.к. они заточены под конвенцию __stdcall, позволяющую напихать дополнительные аргументы в стек и сделать переход к функции в расчёте на то, что стек она почистит.
Для __cdecl же — в общем случае переходник сделать вообще невозможно, а для фиксированного количества аргументов придётся поплясать.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[2]: функтор как указатель на функцию
От: Graf Alex Украина http://grafalex.oberon.kiev.ua
Дата: 23.04.08 14:54
Оценка:
Здравствуйте, Vamp, Вы писали:

V>Непонятно. Если я правильно понял, что filter — это собственная (не библиотечная) функция, то что мешает из нее звать fnmatch с требуемыми параметрами?

А мешает то, что функция scandir должна вызываться из куска кода, который вызывается из разных потоков и с разной маской...
Т.о. маску нельза положить ни в глобальную ни в статическую переменную...
Re: функтор как указатель на функцию
От: Graf Alex Украина http://grafalex.oberon.kiev.ua
Дата: 23.04.08 15:07
Оценка:
Всем спасибо за разъяснение...

Сразу отвечаю на некоторые пункты, дабы не отвечать на каждое письмо в отдельности
1) scandir — Единственный способ получить список файлов в линухе... во всяком случае из известных мне высокоуровневых. Да, тут явная ошибка в дизайне, но деваться мне некуда. По той же причине пнуть создателя я не могу
2) проект кроссплатформенный и хаков писать я не буду. Даже несмотря на то, что код со scandir'ом ограничен #ifdef LINUX
3) поскольку код многопоточный — использование глобальных и статических переменных отпадает
4) Реализовал я методом вытягивания всех файлов, а потом отсеивания лишних все той же fnmatch. Тут же я задал вопрос скорее из любопытства, возможно ли такое вообще
Re[2]: функтор как указатель на функцию
От: Кодт Россия  
Дата: 23.04.08 15:11
Оценка:
Здравствуйте, ., Вы писали:

.>И вообще, пнуть больно писателя такой функции


Ага, позвонить в университет Беркли, найти авторов BSD...
Я думаю, они уже достаточно в своей жизни икали %)
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[2]: функтор как указатель на функцию
От: Кодт Россия  
Дата: 23.04.08 15:32
Оценка: +1
Здравствуйте, Graf Alex, Вы писали:

GA>1) scandir — Единственный способ получить список файлов в линухе... во всяком случае из известных мне высокоуровневых. Да, тут явная ошибка в дизайне, но деваться мне некуда. По той же причине пнуть создателя я не могу


Не единственный Вместо этого дурного дизайна (возвращающего указатель на массив указателей на dirent, которые потом нужно поштучно грохнуть — что тоже сказочно)
Вызывать opendir() / readdir_r() / closedir(), самому же себе фильтровать, сохранять в подходящем контейнере и сортировать в своё удовольствие.
А если сортировка не нужна, то и сохранять необязательно.

Если очень хочется высокоуровневости — ну перепиши scandir по мотивам.
На чистом Си это, конечно, мучительно будет. На С++ попроще.

А ещё есть boost::filesystem
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re: функтор как указатель на функцию
От: vitalyk  
Дата: 23.04.08 15:56
Оценка:
Здравствуйте, Graf Alex, Вы писали:

GA>Тут наткнулся на проблему....


GA>Другими словами как мне пробросить маску файла в функцию fnmatch?


Если scandir работает (в том числе и вызывает колл-беки) в контексте одного потока (что наверняка так), проблема решается использованием thread local storage. В случае с Windows выглядело б это примерно так:

...
// Где-то во время инициализации...
DWORD dwSlot = ::TlsAlloc(); 

...

// Наша функция-фильтр
int filter( const struct dirent * )
{
    const char * szPattern = reinterpret_cast<const char *>( ::TlsGetValue( dwSlot ) );
    // Используем szPattern, в том числе и отправляем его в fnmatch
    // ...
}

...

// Сохраняем текущее значение tls слота на случай, если кто-то выше по стеку тоже его использует (в том числе и этот фрагмент кода)
void * pOldTlsValue = ::TlsGetValue( dwSlot );

// Задаем маску
const char * szPattern = "*.txt";
::TlsSetValue( dwSlot, const_cast<char *>( szPattern ) );

// Вызываем scandir - filter получит маску из слота
::scandir( ..., ..., &::filter, ... );

// Восстанавливаем старое значение слота
::TlsSetValue( dwSlot, pOldTlsValue );
... << RSDN@Home 1.2.0 alpha 4 rev. 1052>>
Re: придумался хак :)
От: Erop Россия  
Дата: 24.04.08 05:47
Оценка:
Здравствуйте, Graf Alex, Вы писали:

GA>Есть функция, которая делает список файлов в указаной директории...

GA>
GA>int scandir(const char *dir, struct dirent ***namelist,
GA>              int(*filter)(const struct dirent *),
GA>              int(*compar)(const struct dirent **, const struct dirent **));

GA>

GA>Внутри этой функции вызывается коллбек-функция filter для того, что бы узнать подходит ли нам некоторый файл или нет...

Конечно удобным и регулярным решением является передача параметров через tread loacl переменную.
Но, если охота извращаться, то можно устроить такой вот хак (пишу из головы, так что это С++ "приблизительно"):

class ThunkFunc {
public:
    typedef bool TParamlessCallback();
    typedef void* TParam;
    typedef bool TCallback( TParam );

    static TParamlessCallback* GetCallback( TCallback* foo, TParam param )
    {
        assert( foo != 0 );
        ThunkFunc* curr = firstFree;
        assert( curr != 0 );
        firstFree = curr->next;
        TParamlessCallback* res = curr->getFuction( foo, param );
        assert( res != 0 && allocated[res] == 0 );
        allocated[res] = curr;
        return res;
    }
    static void FreeCallback( TParamlessCallback* res )
    {
        assert( res != 0 );
        ThunkFunc* curr = allocated[res];
        assert( curr != 0 );
        allocated[res] = 0;
        curr->insertMeAsFree();
    }
    static int FreeCallbacksCount()
    {
        int count = 0;
        for( ThunkFunc* curr = firstFree; curr != 0; curr = curr->next )
            count++;
        return count;
        
    }
    static int TotallRegisteredCollbaks() { return regCount; }

protected:
    ThunkFunc() : next( 0 ) { }
    
    virtual TParamlessCallback* getFuction( TCallback*, TParam ) = 0;
    virtual void freeFunction() = 0;
    virtual bool isFree() const = 0;

    void regMe()
    {
        insertMeAsFree();
        regCount++;
    }

private:
    ThunkFunc* next;
    typedef std::map<TParamlessCallback*, ThunkFunc*> TAllocated;
    static TAllocated allocated;
    static ThunkFunc* firstFree;
    static int regCount;

    void insertMeAsFree()
    {
        next = firstFree;
        firstFree = this;
    }
};

ThunkFunc::TAllocated ThunkFunc::allocated;
ThunkFunc* ThunkFunc::firstFree = 0;
int ThunkFunc::regCount = 0;


template<int* seed>
class ThunkFuncImpl : ThunkFunc {
public:
    ThunkFuncImpl() 
    {
        assert( !*seed );
        *seed = true;
        regMe();
    }
private:
    virtual TParamlessCallback* getFuction( TCallback* f, TParam p )
    {
        assert( foo == 0 && f != 0 );
        foo = f;
        param = p;
        return theCallback;
    }
    virtual void freeFunction()
    {
        assert( foo != 0 );
        foo = 0;
    }
    virtual bool isFree() const
    {
        return foo != 0;
    }

    static TCallback* foo;
    static TParam param;
    static bool theCallback() { return foo( param ); }
};

template<int* seed>
ThunkFunc::TCallback* ThunkFuncImpl<seed>::foo = 0;

template<int* seed>
ThunkFunc::TParam ThunkFuncImpl<seed>::param;

#define IMPL_THUNK_FUNС_I2( UNIQUE_ID )                                            \
    namespace{                                                                    \
        int ThunkFuncSeed_##UNIQUE_ID = false;                                    \
        ThunkFuncImpl< & ThunkFuncSeed_##UNIQUE_ID > ThunkFuncImpl_##UNIQUE_ID;    \
    }    // namespace                                                            \


#define IMPL_THUNK_FUNС_I1( UNIQUE_ID ) IMPL_THUNK_FUNС_I2( UNIQUE_ID )

#define IMPL_THUNK_FUNС_I IMPL_THUNK_FUNС_I1( __LINE__ )

IMPL_THUNK_FUNС_I
IMPL_THUNK_FUNС_I
IMPL_THUNK_FUNС_I
IMPL_THUNK_FUNС_I
IMPL_THUNK_FUNС_I
IMPL_THUNK_FUNС_I
IMPL_THUNK_FUNС_I
IMPL_THUNK_FUNС_I
IMPL_THUNK_FUNС_I
IMPL_THUNK_FUNС_I
IMPL_THUNK_FUNС_I
IMPL_THUNK_FUNС_I
IMPL_THUNK_FUNС_I
IMPL_THUNK_FUNС_I
IMPL_THUNK_FUNС_I
IMPL_THUNK_FUNС_I


Можно, кстати, заставить клиентов ждать на семафоре со счётчиком равным ThunkFunc::TotallRegisteredCollbaks() -- тогда всё будет вообще хорошо. Только ещё надо аллокацию/освобождение колбэка сериализовать...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: функтор как указатель на функцию
От: Аноним  
Дата: 24.04.08 07:02
Оценка: :)
Здравствуйте, Graf Alex, Вы писали:

GA>Тут наткнулся на проблему....


GA>Есть функция, которая делает список файлов в указаной директории...

GA>
GA>int scandir(const char *dir, struct dirent ***namelist,
GA>              int(*filter)(const struct dirent *),
GA>              int(*compar)(const struct dirent **, const struct dirent **));

GA>

GA>Внутри этой функции вызывается коллбек-функция filter для того, что бы узнать подходит ли нам некоторый файл или нет...

GA>Есть так же вспомогательная функция:

GA>
GA>int fnmatch(const char *pattern, const char *string, int flags);
GA>

GA>Первый параметр — маска файла, второй параметр — имя файла которое нужно проматчить по маске...

GA>Задача: написать функтор, в который я бы мог положить маску, и что бы этот функтор вел себя как обычная сишная функция. Другими словами как мне пробросить маску файла в функцию fnmatch?


а чем не угодил просто функтор с оператором ()(const struct dirent *)? или нет возможности править scandir
чем плох boost::function + boost::bind?

вообщем не вижу проблемы.
Re[2]: функтор как указатель на функцию
От: Graf Alex Украина http://grafalex.oberon.kiev.ua
Дата: 24.04.08 07:17
Оценка:
Здравствуйте, Аноним, Вы писали:
А>а чем не угодил просто функтор с оператором ()(const struct dirent *)? или нет возможности править scandir
Как я уже писал, функция scandir — библиотечная... И никто переписывать ее не будет
А>чем плох boost::function + boost::bind?
Может, конечно и не плох... но как им пользоваться я не знаю...
с примером — велкам
Re[2]: функтор как указатель на функцию
От: sokel Россия  
Дата: 24.04.08 07:33
Оценка: 2 (1)
Здравствуйте, Graf Alex, Вы писали:

GA>Всем спасибо за разъяснение...


GA>Сразу отвечаю на некоторые пункты, дабы не отвечать на каждое письмо в отдельности

GA>1) scandir — Единственный способ получить список файлов в линухе... во всяком случае из известных мне высокоуровневых. Да, тут явная ошибка в дизайне, но деваться мне некуда. По той же причине пнуть создателя я не могу

а чем glob не подходит?
Re: функтор как указатель на функцию
От: rg45 СССР  
Дата: 24.04.08 08:17
Оценка:
Здравствуйте, Graf Alex, Вы писали:

GA>Задача: написать функтор, в который я бы мог положить маску, и что бы этот функтор вел себя как обычная сишная функция. Другими словами как мне пробросить маску файла в функцию fnmatch?


Я несколько лет назад сталкивался с аналогичной проблемой: как функциональный объект превратить в указатель на функцию. Был применен грязный хак, но решение получилось вполне рабочее. В двух словах идея в следующем: в динамической памяти выделяется блок(блоки) исполняемого кода. Этот код полностью соответствует коду обычной функции, которая делегирует переданные ей параметры функтору, this которого, как и вызываемой функции-члена, были "прошиты" непосредственно в коде. Адреса этих блоков памяти интерпретирповались как точки входа в функции с соответствуюшими сигнатурами. Формирование таких блоков — задача интересная сама по себе, если заинтересует, могу изложить мое решение.
--
Справедливость выше закона. А человечность выше справедливости.
Re[2]: функтор как указатель на функцию
От: rg45 СССР  
Дата: 24.04.08 08:36
Оценка:
Здравствуйте, Аноним, Вы писали:

А>а чем не угодил просто функтор с оператором ()(const struct dirent *)? или нет возможности править scandir

А>чем плох boost::function + boost::bind?

Тем, что внутри функции scandir идет обращение к указателю на функцию, а не вызов функции-члена operator() функционального объекта. А о том, что scandir нельзя править, говорилось.
--
Справедливость выше закона. А человечность выше справедливости.
Re[2]: функтор как указатель на функцию
От: . Великобритания  
Дата: 24.04.08 09:03
Оценка: +1
rg45 wrote:

> Я несколько лет назад сталкивался с аналогичной проблемой: как

> функциональный объект превратить в указатель на функцию. Был применен
> грязный хак, но решение получилось вполне рабочее. В двух словах идея в
> следующем: в динамической памяти выделяется блок(блоки) исполняемого
> кода. Этот код полностью соответствует коду обычной функции, которая
> делегирует переданные ей параметры функтору, /this/ которого, как и
> вызываемой функции-члена, были "прошиты" непосредственно в коде. Адреса
> этих блоков памяти интерпретирповались как точки входа в функции с
> соответствуюшими сигнатурами. Формирование таких блоков — задача
> интересная сама по себе, если заинтересует, могу изложить мое решение.
Ты начни с того, насколько это переносимо, будет ли это работать с DEP?

А так, самое правильное решение — не использовать scandir, а сделать самому через opendir/readdir/closedir.
Posted via RSDN NNTP Server 2.1 beta
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[3]: функтор как указатель на функцию
От: rg45 СССР  
Дата: 24.04.08 09:27
Оценка:
Здравствуйте, ., Вы писали:

R>> Я несколько лет назад сталкивался с аналогичной проблемой: как

R>> функциональный объект превратить в указатель на функцию. Был применен
R>> грязный хак, но решение получилось вполне рабочее.

.>Ты начни с того, насколько это переносимо, будет ли это работать с DEP?


С переносимостью очевидные проблемы. Я ж так и говорю: "грязный хак".

.>А так, самое правильное решение — не использовать scandir, а сделать самому через opendir/readdir/closedir.

+1
--
Справедливость выше закона. А человечность выше справедливости.
Re[2]: Понедельник начинается в субботу? :)
От: Erop Россия  
Дата: 24.04.08 10:03
Оценка: :))) :)
Здравствуйте, Аноним, Вы писали:

А>вообщем не вижу проблемы.


Как известно, главное в умении ходить сквозь стены -- не видеть препятствий
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: функтор как указатель на функцию
От: Erop Россия  
Дата: 24.04.08 10:08
Оценка: 4 (1)
Здравствуйте, rg45, Вы писали:

R>Я несколько лет назад сталкивался с аналогичной проблемой: как функциональный объект превратить в указатель на функцию. Был применен грязный хак, но решение получилось вполне рабочее. В двух словах идея в следующем: в динамической памяти выделяется блок(блоки) исполняемого кода. Этот код полностью соответствует коду обычной функции, которая делегирует переданные ей параметры функтору, this которого, как и вызываемой функции-члена, были "прошиты" непосредственно в коде. Адреса этих блоков памяти интерпретирповались как точки входа в функции с соответствуюшими сигнатурами. Формирование таких блоков — задача интересная сама по себе, если заинтересует, могу изложить мое решение.


В принципе, с практической точки зрения, достаточно иметь пул таких функций какого-то предопределённого размера. И просто, когда такая функция нужна, аллокировать функцию из пула, прописывать в неё параметры, вызывать scandir, ну а потом возвращать функцию в пул.
По идее число функций из пула нужных одновременно довольно ограниченно по жизни, кроме того, его можно ограничить при помощи семафора. Типа если больше 16 потоков хочет одновременно позвать scandir, то все, начиная с 17-го ждут своей очереди...

Именно ткие рассуждения привели меня к такому вот решению
Автор: Erop
Дата: 24.04.08
.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: функтор как указатель на функцию
От: vitalyk  
Дата: 24.04.08 11:09
Оценка: +2
Здравствуйте, ., Вы писали:

.>Ты начни с того, насколько это переносимо, будет ли это работать с DEP?


В рамках одной архитектуры процессора — вполне переносимо (другими словами, под каждую архитектуру нужно писать свои переходники, как сделано в ATL). С DEP работать будет, если нормально реализовать (достаточно выделять память под санки через VirtualAlloc c PAGE_EXECUTE_READWRITE).
... << RSDN@Home 1.2.0 alpha 4 rev. 1052>>
Re[4]: функтор как указатель на функцию
От: rg45 СССР  
Дата: 24.04.08 11:17
Оценка:
Здравствуйте, vitalyk, Вы писали:

V>Здравствуйте, ., Вы писали:


.>>Ты начни с того, насколько это переносимо, будет ли это работать с DEP?


V>В рамках одной архитектуры процессора — вполне переносимо (другими словами, под каждую архитектуру нужно писать свои переходники, как сделано в ATL). С DEP работать будет, если нормально реализовать (достаточно выделять память под санки через VirtualAlloc c PAGE_EXECUTE_READWRITE).


Еще есть проблема с разными размерами указателей на данные и испоняемый код.
--
Справедливость выше закона. А человечность выше справедливости.
Re: функтор как указатель на функцию
От: brovushkin Украина  
Дата: 24.04.08 20:21
Оценка:
// Если число масок ограничено, то можно попытаться сделать наподобие этого примера
// пример использования scandir взят из man scandir
// strcmp заменить на fnmatch
// test1.cpp
#include <stdio.h>
#include <string.h>
#include <dirent.h>
#include <stdlib.h>

struct Mask1
{
        static const char *name()
        {
                return "test1.cpp";
        }
};

struct Mask2
{
        static const char *name()
        {
                return "test2.cpp";
        }
};

template<class M>
struct FnMacher
{
        static int filter(const struct dirent *entry)
        {
                const char *name = entry->d_name;
                int r = strcmp(name, M::name());

                return (r == 0);
        }
};

int main()
{
        struct dirent **namelist;
        int n = scandir(".", &namelist, &FnMacher<Mask1>::filter, 0);

        if (n < 0)
           perror("scandir");
        else 
        {
           while (n--) 
           {
                   printf("Mask1: %s\n", namelist[n]->d_name);
                   free(namelist[n]);
           }

           free(namelist);
        }

        n = scandir(".", &namelist, &FnMacher<Mask2>::filter, 0);

        if (n < 0)
           perror("scandir");
        else 
        {
           while (n--) 
           {
                   printf("Mask2: %s\n", namelist[n]->d_name);
                   free(namelist[n]);
           }

           free(namelist);
        }

        return 0;
}
Re[5]: функтор как указатель на функцию
От: Erop Россия  
Дата: 24.04.08 21:17
Оценка:
Здравствуйте, rg45, Вы писали:

R>Еще есть проблема с разными размерами указателей на данные и испоняемый код.


Да вообще проблем много довольно. Например на PPC есть специальный регистр, который аддресует 64К памяти, к которой есть быстрый доступ. Компиляторы часто располагают там всякие нужные по ходу пьесы статические данные. Соответсвенно, если позвать функцию, а в регистре этом не то передать, то а-та-та будет. Так что приходится иметь в указателе на функцию два числа -- адрес кода и адрес, который должен оказаться в таком регистре. Ну а как в таких условиях рожать свой код -- вопрос тоде довольно прикольный
И совсем-совсем-совсем не портабл.
Когда я в прошлый раз в такую фигню упёрся, я в конце концов придумал как ничего не компилировать и иметь приемлемую производительность тем не менее.
Так что я бы компиляции избегал бы всеми ногами и руками
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: функтор как указатель на функцию
От: Graf Alex Украина http://grafalex.oberon.kiev.ua
Дата: 25.04.08 07:25
Оценка:
Здравствуйте, sokel, Вы писали:

S>Здравствуйте, Graf Alex, Вы писали:


GA>>Всем спасибо за разъяснение...


GA>>Сразу отвечаю на некоторые пункты, дабы не отвечать на каждое письмо в отдельности

GA>>1) scandir — Единственный способ получить список файлов в линухе... во всяком случае из известных мне высокоуровневых. Да, тут явная ошибка в дизайне, но деваться мне некуда. По той же причине пнуть создателя я не могу

S>а чем glob не подходит?

Не нашел для C++
Re[4]: функтор как указатель на функцию
От: Graf Alex Украина http://grafalex.oberon.kiev.ua
Дата: 25.04.08 07:26
Оценка:
Здравствуйте, Graf Alex, Вы писали:

GA>Здравствуйте, sokel, Вы писали:


S>>Здравствуйте, Graf Alex, Вы писали:


GA>>>Всем спасибо за разъяснение...


GA>>>Сразу отвечаю на некоторые пункты, дабы не отвечать на каждое письмо в отдельности

GA>>>1) scandir — Единственный способ получить список файлов в линухе... во всяком случае из известных мне высокоуровневых. Да, тут явная ошибка в дизайне, но деваться мне некуда. По той же причине пнуть создателя я не могу

S>>а чем glob не подходит?

GA>Не нашел для C++
Упс.. не там искал
Re[2]: придумался хак :)
От: Left2 Украина  
Дата: 26.04.08 12:18
Оценка:
E>Можно, кстати, заставить клиентов ждать на семафоре со счётчиком равным ThunkFunc::TotallRegisteredCollbaks() -- тогда всё будет вообще хорошо.

Сдаётся мне что решение с семафором будет потенциальным источником дедлоков. Из интерфейса функции-то не видно что кто-то с кем-то тут будет синхронизироваться, и если callback-функции будут в свою очередь вызывать scandir, то могут быть траблы. Так что имхо уж лучше TLS или thunk-и.
... << RSDN@Home 1.2.0 alpha rev. 717>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.