![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| Cheloveck |
|
||||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1578 Регистрация: 26.7.2008 Где: Тула Репутация: 3 Всего: 32 |
Извиняюсь за банальную тему, но полазив по интернетам ничего толкового не нашёл.
Итак. Есть закрытая библиотека на Си, одна из функций которой возвращает результат своей деятельности в колбек. У меня в программе её вызывает, естественно, метод класса. Задача - получить данные в конкретный экземпляр. В Сети самый распространённый вариант - использование статических методов в качестве колбека, но тогда нет доступа к членам конкретного объекта. Теперь на примере. Допустим мы имеем потенциальную библиотеку с таким вот кодом
Функция принимает указатель на функцию и вызывает её с неким параметром, который и нужно получить конечному объекту. В нашей программе имеется некий класс
Для наглядности показываем сообщение. Часть данных берётся из конкретного объекта, часть из параметра колбека. Используется примерно так
В итоге должно быть два месаджбокса с текстом "Hello" и заголовками "i'm first" и "i'm second". Хорошо бы найти унивирсальное решение как для stdcall так и для cdecl колбеков. В случае с с stdcall нужно только добавить в ecx указатель this, а в cdecl ещё и перекопировать параметры. Может уже есть готовые решения, что-то не очень горю желанием писать ассемблерные вставки? -------------------- ![]() |
||||||
|
|||||||
| SenkraD |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 933 Регистрация: 3.2.2006 Где: Украина::Киев Репутация: 2 Всего: 23 |
Cheloveck, можно попробовать boost::function (boost::bind):
Добавлено через 9 минут и 6 секунд Звиняюсь, ошибся - нету оператора приведения к поинтеру на функу -> мое решение не верно Добавлено через 14 минут и 24 секунды вот нашёл ещё это |
|||
|
||||
| djamshud |
|
||||||||||||
![]() Пердупержденный ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 23.11.2009 Репутация: 8 Всего: 39 |
Я бы сделал это так (типы немного поменял, но суть сохранилась):
Закрытая библиотека:
Сласс
Подготовка к колбекам:
Вызов функции с колбеком:
Результат:
Это сообщение отредактировал(а) djamshud - 27.11.2009, 15:29 -------------------- 'Cuz I never walk away from what I know is right Alice Cooper - Freedom |
||||||||||||
|
|||||||||||||
| Cheloveck |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1578 Регистрация: 26.7.2008 Где: Тула Репутация: 3 Всего: 32 |
djamshud, решение для одного потока более или менее подходит, но при появлении второго всё станет печально.
SenkraD, пока не увидел решения этой проблемы, но я ещё поизучаю эту тему. -------------------- ![]() |
|||
|
||||
| djamshud |
|
|||
![]() Пердупержденный ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 23.11.2009 Репутация: 8 Всего: 39 |
>решение для одного потока более или менее подходит, но при появлении второго всё станет печально.
Да, это вполне очевидно. Для потокобезопасного решения нужно организовывать очередь из пар объект-колбек.и запускать в отдельном потоке обработчик этой очереди. Хотя это уже попахивает извращением, да еще и функции, работающие с колбеками, не всегда получится выполнить в другом потоке.. Если время выполнения функции и колбеков невелико, можно просто закрыть мутеком операции присваивания global_object и вызова функции. Когда-то я делал именно так. Там еще была рюшечка в виде произвольного типа класса (т.е. не привязывался непосредственно к Class). Если интересует, могу поискать. В обоих случаях пользоваться будет менее удобно, но в общем терпимо. Сам когда-то мучался с этой проблемой, но найти ничего не получилось и сам додумался только до того, до чего додумался. Возлагал надежды на шаблоны, но не получилось. -------------------- 'Cuz I never walk away from what I know is right Alice Cooper - Freedom |
|||
|
||||
| null56 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 721 Регистрация: 19.3.2008 Репутация: 2 Всего: 12 |
Ну если закрыть глаза на треадсейфность... то колбек метода класса можно вызвать так.... (я приведу рабочий свой пример)
я надеюсь, что я правильно понял вопрос... вызов метода определенного объекта через колбак... внутри метода first я могу пользоваться как данными самого объекта (в данном случае this), так и переданный параметр строку |
|||
|
||||
| null56 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 721 Регистрация: 19.3.2008 Репутация: 2 Всего: 12 |
иными словами, чтобы вызвать колбек метода, нужен сам объект + адрес на метод... в моем примере я делаю это через this, так как вызываю колбек будучи в метода самого объекта... но тоже самое можно сделать и вне методов объета
|
|||
|
||||
| djamshud |
|
|||
![]() Пердупержденный ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 23.11.2009 Репутация: 8 Всего: 39 |
Вы неправильно поняли). Посмотрите первое сообщение топика, а точнее первый кусок "Код С++". Указатель на метод туда никак не впихнуть.
-------------------- 'Cuz I never walk away from what I know is right Alice Cooper - Freedom |
|||
|
||||
| Cheloveck |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1578 Регистрация: 26.7.2008 Где: Тула Репутация: 3 Всего: 32 |
В общем-то посоветовавшись с людьми я пришёл к выводу, что единственного способа не придумать. Поэтому каждый раз нужно изобретать метод для конкретного случая.
Эта тема всплыла у меня на этот раз из-за SQLite, но к нему я нашёл C++ враппер. Посмотрю ещё как он работает (быстро проглядел - там boost), если найду что-то интересное - отпишусь сюда. Всем спасибо, но вопрос по ходу не решаемый (во всяком случае без ассемблера). -------------------- ![]() |
|||
|
||||
| Abyx |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 601 Регистрация: 3.11.2009 Репутация: 1 Всего: 10 |
Cheloveck, при чем тут ассемблер?
|
|||
|
||||
| Abyx |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 601 Регистрация: 3.11.2009 Репутация: 1 Всего: 10 |
если в коллбек передается какое-то значение которое можно использовать как ключ - делать карту объектов, например для оконной функции - map<HWND, YourClass>
если объект 1 на поток, надо использовать TLS, - фактически id потока - ключ для выбора объекта если в коллбек прямо или косвенно не передается никаких значений, позволяющих выбрать нужный объект, то надо создавать уникальные коллбеки либо статически, фиксированное количество - сделать карту<функция,объект>
либо динамически, но это непереносимо, т.к. асм |
|||
|
||||
| Cheloveck |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1578 Регистрация: 26.7.2008 Где: Тула Репутация: 3 Всего: 32 |
Я говорил об универсальном способе, а таких "если" уже много было... -------------------- ![]() |
|||
|
||||
| Abyx |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 601 Регистрация: 3.11.2009 Репутация: 1 Всего: 10 |
Cheloveck, тогда тебе нужна универсальная программа %)
Добавлено через 2 минуты и 27 секунд наиболее универсальный метод - динамически создавать коллбеки, но это привязывает к архитектуре проца и системному АПИ управления свойствами памяти |
|||
|
||||
| Cheloveck |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1578 Регистрация: 26.7.2008 Где: Тула Репутация: 3 Всего: 32 |
Abyx, ничего универсального. Если выделять память и записывать туда то, что требуется для вызова (я об этом говорил в первом посте) и передавать эту область в функцию вместо колбека - то всё будет замечательно. Так работают оконные колбеки в делфях. Но я не хочу асм
-------------------- ![]() |
|||
|
||||
| mes |
|
||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
имхо вместо того чтоб плодить глобальные переменные, легче сделать небольшой враппер над нужными функциями, соответствующий нужной политике программы, например так:
писал на скорую руку, чтоб лишь передать суть, ну и поэтому осталось целое поле деятельности для дальнейшего развития.. |
||||
|
|||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |