Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Замыкания C++ и связь с C callback-ми 
V
    Опции темы
jonie
  Дата 14.1.2011, 10:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 15
Всего: 118



Пусть у нас есть Сишный код:
Код

int newCtx() { return 0;}


typedef void (*cbtype)(int ctx);
void RegisterCallback(cbtype callback)
{
  callback(0);  //вызываем
}


и нам надо такой код превратить в класс С++ (стандартная, кстати задача):
Код

class Ctx{
private:
  int m_ctx;
public:
  Ctx() { m_ctx = newCtx();}
  Start() {
   //(1) мы тут должны зарегистрировать обработчик callback
  }
};


В коде в месте (1) нам нужно начать работу с callback. Естественно, что указанный калбэк должен быть статическим и тем самым в непосредственно реализации этой функции мы не имеем this.


Вопрос: как сделать так, чтобы в нашем callback мы могли бы получить this того объекта, который производил регистрацию? *


*) например в C# можно использовать замыкания вроде
Код

class some {
 public Start() {
  var callback = delegate(int ctx) {
    this.foo(); //"затягиваем" this в делегат
  }
  
  register(callback);
 }
}

Но как такое сделать в C++ при указанный условиях что-то не дохожу...

 Недорешение:
мы можем сделать связку сишного контекста (int) с Ctx* используя нечто вроде
Код

static std::map<int, Ctx*> map;
 
и при регистрации в Ctx::Start() добавлять в карту маппинг, но это как-то уныло.




--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
azesmcar
Дата 14.1.2011, 10:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



jonie

А в чем проблема передать this как аргумент в callback например с помощью boost::bind? Конечно, придется немного модифицировать функцию RegisterCallback и сделать ее шаблонной, но думаю ничего страшного.
Код

template <typename F>
void RegisterCallback(F callback) {
   ...
}
...
Start() {
   RegisterCallback(boost::bind(my_callback, this, _1));
}


Это сообщение отредактировал(а) azesmcar - 14.1.2011, 11:01
PM   Вверх
mes
Дата 14.1.2011, 11:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(jonie @  14.1.2011,  09:43 Найти цитируемый пост)
и нам надо такой код превратить в класс С++

все зависит от того где регистрируется колбяк и как нужно это отразить на множество объектов.. 
обычно в С делают доп параметр void*, вот его для thisa можно использовать..желательно только сам метод разгрузить через статическую функцию.. 

Цитата(jonie @  14.1.2011,  09:43 Найти цитируемый пост)
например в C# можно использовать замыкания вроде

Цитата(jonie @  14.1.2011,  09:43 Найти цитируемый пост)
Пусть у нас есть Сишный код:

в таком случае Ваше замыкание не подойдет  smile 
а так в C++ есть (boost::/ std:: ) function и bind для организации замыканий..

Добавлено через 2 минуты и 38 секунд
Цитата(azesmcar @  14.1.2011,  09:48 Найти цитируемый пост)
Конечно, придется немного модифицировать функцию RegisterCallback и сделать ее шаблонной, но думаю ничего страшного.

шаблонной не обязательно..  smile 
но насколько я понял, колбяк нужен для Си-функции, тогда эти методы отпадают..

Добавлено через 4 минуты и 34 секунды
вот пример по этой теме :
http://liveworkspace.org/code/f3ee5f16c898...b005f46d06d1339
из соседней темы :
http://forum.vingrad.ru/forum/topic-320038.html

Это сообщение отредактировал(а) mes - 14.1.2011, 11:13


--------------------
PM MAIL WWW   Вверх
jonie
Дата 14.1.2011, 11:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 15
Всего: 118



ага, callback нужен для сишной функции и только для неё. Модифицировать Сишный код никак нельзя.
void* userObject - такого Сишная либа не предусматривает (см. выше). Еслиб можно  было - не было бы проблем - именно как тут http://liveworkspace.org/code/f3ee5f16c898...b005f46d06d1339 яб  и сделал не думая 8)
Еще раз для понимая: всё что есть это контекст, который также создается Си либой. И это внутренее "нечто" этой либы.

Цитата(mes @  14.1.2011,  11:13 Найти цитируемый пост)

в таком случае Ваше замыкание не подойдет  smile 

если говорить про C# код, то подойдет и будет работать. Я вроде не ошибаюсь в этом месте...

Еще варианты?

Вот тут чувак пишет что ниче у меня не выйдет (первый ответ): http://stackoverflow.com/questions/2001604...d-boostfunction

Это сообщение отредактировал(а) jonie - 14.1.2011, 11:35


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
mes
Дата 14.1.2011, 11:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(jonie @  14.1.2011,  10:34 Найти цитируемый пост)
если говорить про C# код

так Вам для Сишной функции надо то  smile 

так какие параметры предусмотрены ? если никаких, то по какому принципу отражать на множество объектов ?
а если нужно на один, то решается просто - заведите статическую переменную под нужный this..

Добавлено @ 11:44
Цитата(jonie @  14.1.2011,  10:34 Найти цитируемый пост)
Вот тут чувак пишет что ниче у меня не выйдет (первый ответ): 

там Вы привели совсем другую функцию..  smile  но то что Вы написали MyТype ничего не говорит..
для ответа на ваш вопрос нужно знать, что есть эти параметры на самом деле.. 
в общем Вам нужно определить есть ли среди параметров такой, вместо которого можно подсунуть this...





Это сообщение отредактировал(а) mes - 14.1.2011, 11:47


--------------------
PM MAIL WWW   Вверх
jonie
Дата 14.1.2011, 11:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 15
Всего: 118



Цитата(mes @  14.1.2011,  11:38 Найти цитируемый пост)

так какие параметры предусмотрены ? если никаких, то по какому принципу отражать на множество объектов ?
никаких, увы..

Цитата(mes @  14.1.2011,  11:38 Найти цитируемый пост)

а если нужно на один, то решается просто - заведите статическую переменную под нужный this.. 

этот метод я описывал в топике под именем "Недорешение" ..

ну да, наверно иначе и никак не получится... ведь в функции я действительно никак не узнаю о this как бы не старался.

Хотя C# вот как-то выкручивается.. надо почитатьс как он это делает. Наверно такой же метод использует в конечном итоге.

Это сообщение отредактировал(а) jonie - 14.1.2011, 11:46


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
mes
Дата 14.1.2011, 11:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(jonie @  14.1.2011,  10:45 Найти цитируемый пост)
никаких, увы..

тогда нужно определиться :
Цитата(mes @  14.1.2011,  10:38 Найти цитируемый пост)
 по какому принципу отражать на множество объектов ?




Цитата(jonie @  14.1.2011,  10:45 Найти цитируемый пост)
этот метод я описывал в топике под именем "Недорешение" ..

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



--------------------
PM MAIL WWW   Вверх
mes
Дата 14.1.2011, 12:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(mes @  14.1.2011,  10:50 Найти цитируемый пост)
тогда нужно определиться :
Цитата(mes @  14.1.2011,  10:38 )
 по какому принципу отражать на множество объектов ?

например, можно на каждый адрес функции колбяка отразить свой делегат... 

вот пример для размышления и допиливания под свои нужды :
http://liveworkspace.org/code/47d75b234a07...8c569f74af6a251

Это сообщение отредактировал(а) mes - 14.1.2011, 12:29


--------------------
PM MAIL WWW   Вверх
jonie
Дата 14.1.2011, 12:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 15
Всего: 118



ну я собственно так и сделал у себя, но мне чет не особо понравилось 8)


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
mes
Дата 14.1.2011, 12:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(jonie @  14.1.2011,  11:19 Найти цитируемый пост)
 но мне чет не особо понравилось 

ну а поконкретней, чего не понравилось то ?

Добавлено через 3 минуты и 34 секунды
Цитата(jonie @  14.1.2011,  11:19 Найти цитируемый пост)
ну я собственно так и сделал у себя, 

если Вы об этом
Цитата(jonie @  14.1.2011,  09:43 Найти цитируемый пост)
мы можем сделать связку сишного контекста (int) с Ctx* используя нечто вроде

то это совсем другое.. в примере нет (ран-тайм) карты и ассоциация метода идет к адресу функции колбяка... 


--------------------
PM MAIL WWW   Вверх
mes
Дата 14.1.2011, 12:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



вот еще вариантик:
http://liveworkspace.org/code/eddee3669c8a...14f172d741cf696

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

Это сообщение отредактировал(а) mes - 14.1.2011, 13:10


--------------------
PM MAIL WWW   Вверх
azesmcar
Дата 14.1.2011, 13:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(jonie @  14.1.2011,  11:34 Найти цитируемый пост)
Модифицировать Сишный код никак нельзя.

т.е. даже добавлять аргумент в callback нельзя? тогда единственный вариант - получить указатель из какого нибудь глобального контейнера, т.е.

Цитата(jonie @  14.1.2011,  10:43 Найти цитируемый пост)
Недорешение

 smile 

PM   Вверх
jonie
Дата 14.1.2011, 13:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 15
Всего: 118



Цитата(mes @  14.1.2011,  12:20 Найти цитируемый пост)

если Вы об этом
Цитата

Цитата(jonie @  14.1.2011,  09:43 Найти цитируемый пост)
мы можем сделать связку сишного контекста (int) с Ctx* используя нечто вроде


то это совсем другое.. в примере нет (ран-тайм) карты и ассоциация метода идет к адресу функции колбяк

ну это понятно. Я имел в виду что в общем связь хранится в неком статической внешней (по отношениею к создавающему объекту) переменной. А вот что хранится  ней: указатель ли на объект или указатель на функцию в этом объекте на самом деле не важно.

этак можно  и до boost::signals2 дойти )

Это сообщение отредактировал(а) jonie - 14.1.2011, 13:32


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
mes
Дата 14.1.2011, 13:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(jonie @  14.1.2011,  12:29 Найти цитируемый пост)
. Я имел в виду что в общем связь хранится в неком статической внешней (по отношениею к создавающему объекту) переменной.

ну так естественно, если нет (подходящего) параметра, то нужна связь.. вопрос в том какой род связи подойдет лучше для задачи smile

Добавлено через 2 минуты и 51 секунду
Цитата(jonie @  14.1.2011,  12:29 Найти цитируемый пост)
й. А вот что хранится  ней: указатель ли на объект или указатель на функцию в этом объекте на самом деле не важно.

это да.. вопрос не в том, что хранится, а к чему ассоциировано то, что хранится..

Добавлено через 5 минут и 10 секунд
Цитата(jonie @  14.1.2011,  12:29 Найти цитируемый пост)
 внешней (по отношениею к создавающему объекту) 

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




--------------------
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0983 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.