1 | ||||||||||||||||
Std::function<>::target() возвращает 019.07.2014, 17:52. Показов 2670. Ответов 11
Метки нет (Все метки)
Привет!
Не удовольствия для, а фриланса ради пришлось работать с WinAPI. Всем известно, что это чистый С. Так вот захотел я привязать callback процедуру к объекту и скормить это дело API.
0
|
19.07.2014, 17:52 | |
Ответы с готовыми решениями:
11
Class member function to std::function Std::function vs auto Скотт Мэйерс Проблема с заданием шаблона метода с параметром const std::function<T()> Не могу разобраться как обновить в std::map<std::string, вектор_структур> |
What a waste!
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
|
|
19.07.2014, 20:55 | 2 |
Мне кажется хранимый тип в proc - это не DLGPROC, а тип, генерируемый std::bind.
1
|
19409 / 10028 / 2443
Регистрация: 30.01.2014
Сообщений: 17,678
|
|
19.07.2014, 23:36 | 3 |
CALLBACK должен быть статической функцией класса или свободной функцией.
Как ты себе представляешь в противном случае сохранение контекста this при таком преобразовании: ?
0
|
28 / 23 / 12
Регистрация: 25.08.2013
Сообщений: 44
|
||||||
19.07.2014, 23:41 | 4 | |||||
Kastaneda, нельзя просто так передать в Вин АПИшную функцию метод класса и никакой бинд тут не поможет. Можно воспользоваться тем свойством, что лямбды без захвата конвертируются в обычную функцию, которую передать не проблема.
Например это может выглядеть так:
0
|
19409 / 10028 / 2443
Регистрация: 30.01.2014
Сообщений: 17,678
|
|
19.07.2014, 23:54 | 5 |
Kastaneda, короче говоря, сигнатура функции, которая получается через target должна полностью соответствовать сигнатуре сохраненной в std::function. Если ты сохранил одно (метод класса), а пытаешься получить другое (указатель на свободную функцию), то поэтому и возвращается ноль.
Добавлено через 6 минут StailGot, Я, честно говоря, не очень хорошо знаю это API, но я точно знаю, что в нормальном API с коллбэками должен быть способ передачи контекста (обычно делают void * параметр с user data). Насколько я понял, Kastaneda вступил на этот узкий путь именно из-за необходимости передачи контекста (this). Твое решение с лямбдой эту проблему не решает. Можешь подсказать, возможно ли передать контекст в этом API?
0
|
28 / 23 / 12
Регистрация: 25.08.2013
Сообщений: 44
|
||||||
20.07.2014, 00:43 | 6 | |||||
Сообщение было отмечено Kastaneda как решение
Решение
DrOffset, DialogBoxIndirect - это макрос для DialogBoxIndirectParam (и это тоже макрос), где последним передается пользовательский параметр, LPARAM dwInitParam, в который передается при первом же вызове callbac'a, событие WM_INITDIALOG. Тут же он просто равен нулю. Так что да, если передать указатель (this), преобразовав его в LPARAM и потом обратно привести к классу, то должно получится. Тут кстати лямбда и пригодится.
Добавлено через 12 минут Пример передачи строки, с классом примерно тоже самое:
2
|
19409 / 10028 / 2443
Регистрация: 30.01.2014
Сообщений: 17,678
|
|
20.07.2014, 01:18 | 7 |
А как быть с последующими вызовами? Если, например, на событие WM_CLOSE захочется вызвать какой-то метод класса? Собственно именно поэтому я и не стал предлагать автору решение через этот параметр (естественно я посмотрел MSDN прежде чем спрашивать тебя). Или, все-таки, я чего-то недопонял?
0
|
28 / 23 / 12
Регистрация: 25.08.2013
Сообщений: 44
|
|
20.07.2014, 01:32 | 8 |
Создать static переменную в callbac'e, куда и сохранить указатель на класс при первом вызове.
0
|
19409 / 10028 / 2443
Регистрация: 30.01.2014
Сообщений: 17,678
|
|
20.07.2014, 03:20 | 9 |
К сожалению это решение с большим количеством недостатков. Ну да ладно, пусть автор решает подойдет ему или нет.
0
|
20.07.2014, 11:49 [ТС] | 10 |
Спасибо за ответы. Да, моя цель была в том, чтобы протащить this в процедуру. С новыми фишками С++11 плотно не работал, поэтому и сделал такую глупость.
Ладно, раз по человечески это сделать не получится, тогда Добавлено через 4 минуты StailGot, спасибо за пример, я с WinAPI тоже не много работал, поэтому не знал такого. Думаю логичней всего будет сделать статичный vector<pair<HWND, dialog&>>, куда в процедуре при первом вызове сохранять this, привязанный к хенделу диалога. Таким образом можно будет получить нужный this в любое время.
0
|
Ушел с форума
|
|
20.07.2014, 12:18 | 11 |
В обработчике WM_INITDIALOG запомнить переданный в lParam указатель
через SetWindowLongPtr с кодом GWLP_USERDATA. Потом в любом обработчике его можно извлечь через GetWindowLongPtr с этим же кодом.
1
|
20.07.2014, 12:20 [ТС] | 12 |
Убежденный, спасибо, я как раз писать сел)
0
|
20.07.2014, 12:20 | |
20.07.2014, 12:20 | |
Помогаю со студенческими работами здесь
12
std::string, std::fstream, ошибка кучи Как проинициализировать std::stack<const int> obj ( std::stack<int>{} ); std::filesystem && std::asio и пр [Build error] No rule to make target 'String.o'. Stop. Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |