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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Динамическая память и длл, как правильно организовать 
:(
    Опции темы
Ander
  Дата 29.8.2004, 10:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 38
Регистрация: 17.11.2003
Где: Рига, Латвия

Репутация: нет
Всего: 1



В общем расклад такой: у меня есть длл-ка, которая работает как хук. Причём на нажатие определённых клавиш она должна выделить память и записать туда инфу. Так вот всякие ASSERTы выскакивают, когда программа работает под разными процессами ( и выделение памяти соответственно). Почему так происходит мне кажется я понял, то есть адрес выделенной памяти действителен только в виртуальном пространстве процесса, выделившего память, а для всех других процессов, где загружен образец данной длл, обращение к данному адресу будет бессмысленным. И, соответственно, когда в конце происходит глобальная чистка, программа пытается освободить память по адресам, которые на самом деле никак с этим делом не связаны. Пока единственный выход я вижу в том, чтобы чтобы выделять память в основной программе (куда можно посылать сообщение с запросом), а не в функциях длл. Но это накладывает зверские ограничения. Например, получается, что для общения основной программы и длл при отправке сообщения я не могу по той же причине передать адрес какой-нибудь структруры, а придётся довольствоваться 64 битами в lParam и wParam. Можно, конечно, послать 10 сообщений, но это же изврат...

Кто может сказать чего дельного по данному вопросу? Советы, линки, поправки - всему буду рад.
PM MAIL   Вверх
mr.DUDA
Дата 29.8.2004, 12:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 25
Всего: 232



Сделай какой-нибудь глобальный расшаренный массив внутри хук-дллки, создай (в той же длл-ке, в DllMain) поток который будет работать во всех процессах (только выставь ему маленький приоритет, иначе многие проги будут просто загибаться), и два каких-нибудь именованных объекта для синхронизации (например, event-ы), которые открывай (OpenEvent) или создавай (если уже существует) внутри DllMain твоей хук-дллки.

Теперь, если нужно передать инфу из одного процесса в другой (например, как у тебя - пришло перехваченное Win-сообщение, и нужно выдернуть из него инфу и сохранить в твоей проге), тогда:

1) сигнализируй с пом. первого event-а о том, что другим процессам ничего нельзя записывать в расшаренный буфер
2) сохраняй из своей ф-ции всю нужную инфу в расшаренном буфере
3) сигнализируй с пом. второго event-а о том, что буфер заполнен
4) в потоке, создаваемом при старте хук-длл, должно быть ожидание (WaitForSingleObject), которое поймает второй event
5) каким-то образом определив, "мне или не мне предназначена инфа", поток внутри каждого отдельного процесса либо продолжит работу либо прочитает инфу из буфера, сбросив после этого первый event


--------------------
user posted image
PM MAIL WWW   Вверх
Ander
Дата 29.8.2004, 13:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 38
Регистрация: 17.11.2003
Где: Рига, Латвия

Репутация: нет
Всего: 1



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

#pragma data_seg("SHARED")
     static TCHAR* entries[ENTRY_NUMBER] = {NULL};
#pragma data_seg()
#pragma comment(linker,"/section:SHARED,RWS")


Запускаю программу, в Edit Box пишу какой-нибудь текст, нажимаю нужную комбинацию клавиш, которая приведёт к тому, что скажем в первую запись массива будет помещён указатель на выделенную память. Типа
Код

entries[0] = new TCHAR[entry_length];
...
сохраняем по этому адресу нужный текст
...


Если потом открыть ноутпад (при работающей проге ессно) и попытаться прочитать текст по адресу, хранящемуся в первой (нулевой) записи, то ничего не выйдет, ведь в адресном пространстве ноутпада этот адрес значит совсем другое или не значит ничего. Как быть?
PM MAIL   Вверх
mr.DUDA
Дата 29.8.2004, 15:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 25
Всего: 232



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

Но если уж очень хочется иметь не ограниченный заранее буфер, то можно попробовать поиграться с файлами, отображаемыми на память:

- внутри хук-длл создать файл, отображаемый на память (не привязанный к реальному файлу), сделать его именованным (при создании указать имя для объекта, чтобы можно было потом открыть его из любого процесса с пом. OpenFileMapping)
- размер файла, отображаемого на память, не ограничен - получаем некий аналог памяти, выделяемой динамически
- в этом случае не нужно никаких расшаренных массивов
- для синхронизации и извещений достаточно 2-х event-ов (buffer_busy и buffer_full) и ждущего потока там, где данные принимаются (в твоём примере этот поток должен быть только в основной программе).

Единственный минус при таком способе - это то, что разделяемый объект всего один, поэтому другим потокам придётся ждать его освобождения после того как один поток заполнит буфер (файл, отображаемый на память).

Выйти из этой ситуации можно достаточно просто и красиво: поток, ожидающий поступления сообщений, сразу же забирает данные из буфера и помещает их в какой-нибудь динамический список (очередь) в своём процессе, после чего сразу же сигналит о том, что буфер свободен -- таким образом, никаких задержек нет. Другой поток в твоей проге просто будет проверять, пуста ли очередь, и если нет - то забирать данные из головы очереди.


--------------------
user posted image
PM MAIL WWW   Вверх
Ander
Дата 29.8.2004, 16:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 38
Регистрация: 17.11.2003
Где: Рига, Латвия

Репутация: нет
Всего: 1



Сэнкс, буду двигать в сторону FileMapping
PM MAIL   Вверх
Олег М
Дата 30.8.2004, 05:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 436
Регистрация: 10.6.2004
Где: Москва

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



Ander я решал точно такую же проблему - сделал с помощью FileMapping и потоков.
В общей памяти сделал что-то типа стека, простейшего - работает очень быстро (моя реализация - как система работает с этими данными, другой вопрос), размер - одна страница (порядка сотни событий, не считал, да и заполняться он успевает максимум на 2). При возникновении события обработчик просто в записывает информацию в этот стек. Обработку и сохранение событий я сделал в отдельном ехешнике (мне прятать ничего не надо - задача официальная) - чтоб в ДДЛке не было лишнего кода. Работает прекрасно, ничего не тормозит и не виснет и памяти не жрёт.

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

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

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

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

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


 




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


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

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