![]() |
Модераторы: feodorv, GremlinProg, xvr, Fixin |
![]() ![]() ![]() |
|
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 7 Всего: 459 |
Собственно одно решение нашел в исходниках билдера/делфи. Для каждого объекта выделяется блок памяти под функцию и указатель на объект . В область функции зафигачивают машинные коды для перехода по адресу объектного обработчика ну и дополнительно инициализируют this .
Может кто-то встречал более переносимое решение чем вставка машинных кодов и правка адресов для перехода? Исходников класса CWnd, так можно было еще там подсмотреть решение. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
Dem_max |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1780 Регистрация: 12.4.2007 Репутация: 16 Всего: 39 |
Смотря что за велосипед
-------------------- Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte") |
|||
|
||||
GremlinProg |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
Зачем это? Обработкой всех сообщений очереди занимается поток. Один конкретный поток! Есть ситуации, когда несколько потоков имеют очередь сообщений, но любое окно может принадлежать только одному потоку, следовательно защищать передачу объекта в процедуру окна бессмысленно, ему ничего не грозит даже в глобальном scope. -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 6 Всего: 135 |
а чем std:: или boost:: или на худой конец my_bicycle::bind не угодил ?
-------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
Alexeis |
|
||||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 7 Всего: 459 |
Может не совсем точно объяснил. Задача сделать функцию типа
Не статическим членом класса. К примеру взываем функцию
Для создания диалога, а диалог у нас обернут в класс С++ . Очевидно boost::function никак не станет вместо WndProc или DialogProc . Подсмотрел также решение MFC Они решили вопрос так. Создали глобальрный ассоциативный массив СHandleMap, который с каждым хэндлом ассоциирует указатель на класс CWnd* . Функция окна одна на всех, при приходе очередного сообщения функция лезет в СHandleMap, находит правильный экземпляр наследник CWnd* и вызывает его виртуальную функцию обработки оконных сообщений. Это решение не такое быстрое, но универсальное. Мне хотелось как раз найти вот такое решение как привел borisbn. Cразу вспомнилось boost::function, но видимо не провернуть такой трюк никак. Пока что есть только решение от Microsoft. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
||||
|
|||||
borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 6 Всего: 135 |
Alexeis, я это делал следующим (да... знаю, что извращённым) способом:
-------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
GremlinProg |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
Скорее всего, это реализация событий у борланда, с процедурой окна она не имеет ничего общего, просто борланд унифицирует таким образом делегат (этот подход у него как минимум с Delphi 3-4) Это когда указатель на метод склеивается с указателем на объект и представляется универсальным функтором, который можно вызвать как простую функцию в любом контексте. Насколько я помню, у Borland'а существует глобальный указатель, типа pCreateObject, в который записывается указатель на объект, перед вызовом CreateWindow. Первый вызов процедуры окна просто берет этот указатель и пишет в недра свойств окна или WindowLong (не помню точно), при этом, меняет процедуру окна на штатную, которая извлекает указатель из недр и вызывает для него метод WndProc. -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
Alexeis |
|
||||||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 7 Всего: 459 |
А чо, четенькое решенице. Быстрое и довольно честное. Делегаты у борлонда существуют ввиде структуры из 2х полей. Делегат имеет размер 8 байт и не может быть записан вместо адреса функции и тем более винда не будет вызывать его. Вот собственно привожу весь код создания объектного калбека. Тут правда паскаль, но код такой сиподобный ^. тоже что и -> , знак $ заменяет 0x , Move тоже что и memcpy только аргументы поменяны местами. @ тоже что &
-------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
||||||
|
|||||||
GremlinProg |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
Alexeis, пытается троллить, забавно. В цитате я об этом и написал ![]() только размер делегата равен не 8 байтам, а равен размеру двух указателей (в x64 это 16 байт)
Тут большинство программисты и в общем случае понимают разницу между Object Pascal и Си ![]() Не советую этим пользоваться! Это бессмысленная "кучамала", первым комментарием уже сказал почему. -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 40 Всего: 223 |
Не корысти ради, а токмо точности для - У Борланда существуют оба варианта, и делегаты из 2х указателей (которые в С++ у них называются __closure), и эти самые thunk'и, которые позволяют склеить this и метод в один указатель и приделать еще что нибудь. Второе, в частности, когда то использовалось для реализации таблиц виртуальных методов в множественном наследовании. У них thunk'и двигали this Но все это генерил компилятор в compile time, а то, что показал Alexis делает библиотека VCL в run time Пользоваться можно, но только если других методов уже не осталось ![]() |
|||
|
||||
Dem_max |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1780 Регистрация: 12.4.2007 Репутация: 16 Всего: 39 |
Я собственно использую __closure в С++ Builder, для того чтобы не делать функцию статической.
Для мелкософтовского компилятора это будет __thiscall Но это чисто компиляторозависимый велосипед. -------------------- Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte") |
|||
|
||||
GremlinProg |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
а я об этом как раз и писал, для передачи объекта в процедуру окна городить такой огород бессмысленно и неразумно -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
xvr |
|
||||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 40 Всего: 223 |
Неа. __closure в Builder'е - это модификатор типа указателя, а __thiscall - это calling conversion для функции. На уровне сорцов это сразу видно - __closure указатели вызываются как обычные функции (я имею в виду синтаксис вызова), а __thiscall как члены класса, т.е. для них явно нужно указать this (или вызывать в контексте метода класса, тогда this компилятор подставит сам)
С этим согласен. Если только GWL_USERDATA не занят уже под что то другое. В VCL Borland не мог воспользоваться GWL_USERDATA для передачи this, т.к. GWL_USERDATA находится в распоряжении пользователя библиотеки VCL, а не её самой. |
||||
|
|||||
GremlinProg |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
Для таких случаев существует как минимум 2 пути: 1. использовать свойства окна 2. расширить набор WindowLong (WNDCLASS::cbWndExtra) при регистрации класса (обычный подход)
Для расширения класса (например, для второго варианта) у Borland'а, насколько помню, всегда имелся метод CreateParams, который можно было переписать на свой вкус. -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 6 Всего: 135 |
дык для этого ж они свойство Tag предоставляют -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
![]() ![]() ![]() |
Правила форума "C/C++: Системное программирование и WinAPI" | |
|
На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы . Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |