необычный тип параметров в функции
От: Jumangee Россия  
Дата: 13.03.17 15:14
Оценка:
Добрый день.
Вопрос:
Пишем глобальную callback-функцию. Студия ругается при попытке вызова моей функции:
cannot covert parametr ... to 'void (__cdecl *)(void)'
Слишком сложно для понимания.
1. Как-то можно упростить приведенную конструкцию?
2. Как должен выглядеть прототип моей callback-функции при таком требовании к "входящему параметру"?
Re: необычный тип параметров в функции
От: Erop Россия  
Дата: 13.03.17 15:41
Оценка:
Здравствуйте, Jumangee, Вы писали:

J>cannot covert parametr ... to 'void (__cdecl *)(void)'

J>1. Как-то можно упростить приведенную конструкцию?
Вставь имя переменной в декларатор, если не понимаешь.
Тут будет так:
void (__cdecl*f)(void), то есть f -- это указатель на функцию.

Ну а сама функция должна быть
void __cdecl f(void)


J>2. Как должен выглядеть прототип моей callback-функции при таком требовании к "входящему параметру"?


Вообще в С/С++ действует правило "декларатор выглядит как пример использования)

(void) -- Это С-шная штука, в С++ она эквивалентна просто отсутствию аргументов ()
То есть void (*f)() надо понимать так, что если f разыменовть (*f), и потом вызвать без аргументов
(*f)(), то получится void.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: необычный тип параметров в функции
От: Jumangee Россия  
Дата: 13.03.17 18:48
Оценка:
Разобрался.
Все работает.

1. Вызов callback-функции в качестве параметра:
(void (__cdecl *)(void))foo

2. Прототип callback-функции:
void foo (void *s, const char *sz)

Тема больше не актуальна.
Re[3]: необычный тип параметров в функции
От: Кодт Россия  
Дата: 13.03.17 19:55
Оценка: 12 (1)
Здравствуйте, Jumangee, Вы писали:

J>Тема больше не актуальна.


И всё же, вдогонку, скажу.
Очень часто требуется, чтобы колбек был с контекстом. Таким контекстом может стать объект, чей метод собрались вызвать, или какие-то связанные параметры...
Поэтому, когда проектируется API, принимающий колбеки, то это пожелание учитывается.
Либо в чисто сишном стиле — колбеком является пара (функция, обезличенный аргумент контекста — intptr_t / void*).
Либо в плюсовом — колбеком является std::function, которую строят из лямбды или std::bind.

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

Для непортабельного кода на MFC/ATL/WTL вариант с кодогенерацией был доступен из коробки (кажется, <atlthunk.h>). Хотя это и плохая практика.
Перекуём баги на фичи!
Re[4]: необычный тип параметров в функции
От: AlexGin Беларусь  
Дата: 14.03.17 07:50
Оценка:
Здравствуйте, уважаемый Кодт, Вы писали:

К>Либо в плюсовом — колбеком является std::function, которую строят из лямбды или std::bind.

Я видел информацию, что вариант от boost (т.е. boost::function) — оказывается эффективнее
http://stackoverflow.com/questions/7852101/c-lambda-with-captures-as-a-function-pointer
не проверял, т.к. пользуюсь:
std::function

Есть ли какие-то соображения насчёт применения boost::function вместо std::function?

P.S. Я пытался гуглить, но сравнения не в тему.
Re[5]: необычный тип параметров в функции
От: Кодт Россия  
Дата: 14.03.17 09:36
Оценка: +1
Здравствуйте, AlexGin, Вы писали:

AG>Я видел информацию, что вариант от boost (т.е. boost::function) — оказывается эффективнее

AG>http://stackoverflow.com/questions/7852101/c-lambda-with-captures-as-a-function-pointer

Не знаю, — надо смотреть, что там в потрохах и в бусте, и в стд. От реализации к реализации могут быть сильные различия. И от платформы к платформе.
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.