Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2008.02.24;
Скачать: [xml.tar.bz2];

Вниз

Передача данных в DLL, которые могут быть изменены   Найти похожие ветки 

 
Piter ©   (2008-01-21 19:14) [0]

Есть программа, есть интерфейс общения между ядром и плагинами (выполненных в виде DLL).

Нужно сделать подписку плагина на перехват неких сырых данных. Само указание перехвата не вопрос, указывается callback функция в плагине, которая должна быть вызвана при приходе данных (ну что-то типа хука получается). Но вот заковыка - эти некие сырые данные предоставляются  плагину, но он по идеологии должен уметь не только их читать, но и модифицировать. И все бы ничего, но черт знает буфер какой длины сформирует плагин, он может быть и больше передающихся данных. Передавать буфер с запасом? С каким? Не универсально ;(

Плагин не может освободить память, выделенную ядром, естественно, и наоборот, так как скорее всего разные менеджеры памяти будут... Как бы элегантно проблему решить?


 
Piter ©   (2008-01-21 19:19) [1]

у меня была идея только одна - обговорить, что память под сырые данные должна выделяться функцией VirtualAlloc и соответственно освобождаться VirtualFree. Тогда по идее плагин может управлять памятью выделенной ядром, а ядро памятью выделенной плагином.

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


 
ketmar ©   (2008-01-21 19:23) [2]

вынести менеджер памяти в отдельный модуль (ту же доп. DLL) и постановить, что все юзают его.


 
Черный Шаман   (2008-01-21 19:26) [3]


>
> Piter ©   (21.01.08 19:14)
>
> Есть программа, есть интерфейс общения между ядром и плагинами
> (выполненных в виде DLL).
>
> Нужно сделать подписку плагина на перехват неких сырых данных.
>  Само указание перехвата не вопрос, указывается callback
> функция в плагине, которая должна быть вызвана при приходе
> данных (ну что-то типа хука получается). Но вот заковыка
> - эти некие сырые данные предоставляются  плагину, но он
> по идеологии должен уметь не только их читать, но и модифицировать.
>  И все бы ничего, но черт знает буфер какой длины сформирует
> плагин, он может быть и больше передающихся данных. Передавать
> буфер с запасом? С каким? Не универсально ;(


на Threaddetach в dllmain формировать буфер на который передавать ссылку при возврате данных.


 
ketmar ©   (2008-01-21 19:31) [4]

>[3] Черный Шаман (21.01.08 19:26)
это ты что такое сказал? O_o


 
Petr V. Abramov ©   (2008-01-21 19:35) [5]

если скомпилить с рантайм-пакетами, менеджер памяти будет один.

дальше могу спроть фигню от нечеткого понимания, что же в конце концов надо, итак:

зачему плагину выделять буфер? если он модифицирует данные в контексте ядра, так их длина известна. Если он копирует их к себе - так все равно длина пришедших данных известна, ее достаточно передать параметром вызываемому callback`у


 
Григорьев Антон ©   (2008-01-21 19:43) [6]

Использовать системный менеджер памяти специально для таких случаев. См. CoTaskMemAlloc, CoTaskMemFree.


 
Petr V. Abramov ©   (2008-01-21 19:47) [7]


> Григорьев Антон ©   (21.01.08 19:43) [6]

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


 
Семен Сурков   (2008-01-21 19:52) [8]

рантайтм-пакеты - это рулез.
сейчас, правда Миша скажет, что спрашивал о DLL.
но я полагаю, что это по причине плохого знания технологии BPL.

ЛЮБЫЕ плагины с BPL делаются намного проще, чем в DLL.

Возможно это поможет?
http://softwarer.ru/packages.html

ЗЫ Есно речь, про то, что плугин и хост - это дельфи одной версии.


 
Petr V. Abramov ©   (2008-01-21 19:57) [9]


> Семен Сурков   (21.01.08 19:52) [8]

не проще и не сложней, потому что сущностно BPL и DLL - один хрен


 
Черный Шаман   (2008-01-21 19:58) [10]


> ketmar ©   (21.01.08 19:31) [4]
>
> >[3] Черный Шаман (21.01.08 19:26)
> это ты что такое сказал? O_o


В DLLProc на DLL_THREAD_ATTACH создавать буфер на который передавать ссылки в активную программу. на DLL_THREAD_DETACH уничтожать.

Handle текущей нити не думаю, что проблема узнать.


 
Черный Шаман   (2008-01-21 20:01) [11]


> Petr V. Abramov ©   (21.01.08 19:57) [9]
>
>
> > Семен Сурков   (21.01.08 19:52) [8]
>
> не проще и не сложней, потому что сущностно BPL и DLL -
> один хрен


А если хост - приложение на PB/VB а плагин на Delphi/C++ ? Никогда разруливать не приходилось? Особенно если те кто используют пакеты обладают минимальными знаниями "а чо там в компьютере и системе делаеццо".


 
Piter ©   (2008-01-21 20:20) [12]

ketmar ©   (21.01.08 19:23) [2]
вынести менеджер памяти в отдельный модуль (ту же доп. DLL) и постановить, что все юзают его


Тоже думал об этом... По крайней мере в SDK описать функции по выделению и уничтожению памяти.. но все равно как-то...

Petr V. Abramov ©   (21.01.08 19:35) [5]
зачему плагину выделять буфер? если он модифицирует данные в контексте ядра, так их длина известна


рекомендую таки перечитать сабж.

Это ЯДРО получает некие данные, а плагин ПОДПИСЫВАЕТСЯ на перехват этих данных.

Григорьев Антон ©   (21.01.08 19:43) [6]
Использовать системный менеджер памяти специально для таких случаев. См. CoTaskMemAlloc, CoTaskMemFree.


а чем плох VirtualAlloc / VirtualFree?
Petr V. Abramov ©   (21.01.08 19:47) [7]
а зачем эти танцы? с рантайм-пакетами все равно с менеджером памяти все прекрасно


да где вообще указано, что плагины делаются на Delphi?!?! Сказано же - DLL.

Семен Сурков   (21.01.08 19:52) [8]
сейчас, правда Миша скажет, что спрашивал о DLL


именно о ней и спрашивал

Семен Сурков   (21.01.08 19:52) [8]
но я полагаю, что это по причине плохого знания технологии BPL


опять телепаты набежали ;)


 
ketmar ©   (2008-01-21 20:27) [13]

>[10] Черный Шаман (21.01.08 19:58)
редкая дурь, однако…


 
ketmar ©   (2008-01-21 20:28) [14]

>[12] Piter ©(21.01.08 20:20)
>Тоже думал об этом... По крайней мере в SDK описать функции по выделению
>и уничтожению памяти.. но все равно как-то...

тогда пиши на java.


 
Petr V. Abramov ©   (2008-01-21 20:29) [15]


> Это ЯДРО получает некие данные, а плагин ПОДПИСЫВАЕТСЯ на
> перехват этих данных.

да это-то я первого раза понял :)

> да где вообще указано, что плагины делаются на Delphi?!?
> ! Сказано же - DLL.


но сути дела это не меняет. ядро получает данные. длина ЯДРУ известна? известна. ядро вызывает callback, которому в качестве параметра передает указатель на данные и их длину. Когда надо ЯДРО освобождает память.


 
ketmar ©   (2008-01-21 20:30) [16]

>[15] Petr V. Abramov ©(21.01.08 20:29)
[0]
>И все бы ничего, но черт знает буфер какой длины сформирует плагин, он
>может быть и больше передающихся данных.


 
Petr V. Abramov ©   (2008-01-21 20:33) [17]


> ketmar ©   (21.01.08 20:30) [16]

а какого хрена плагин формирует буфер? вот зачем? из сабжа это непонятно.
ядро принимает, ядро пусть и формирует и освобождает, а плагин играется в пределах буфера.


 
ketmar ©   (2008-01-21 20:38) [18]

>[17] Petr V. Abramov ©(21.01.08 20:33)
а какая разница? ну вот в процессе обработки что-то добавил. так получилось. сколько он добавит — он не знает заранее. в чём проблема? вполне реальный сценарий.


 
Petr V. Abramov ©   (2008-01-21 20:43) [19]


> ketmar ©   (21.01.08 20:38) [18]

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


 
Sergey Masloff   (2008-01-21 21:26) [20]

я бы использовал CoTaskMemAlloc как и указано в [6]


 
Petr V. Abramov ©   (2008-01-22 00:48) [21]


> Sergey Masloff   (21.01.08 21:26) [20]

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


 
Григорьев Антон ©   (2008-01-22 08:55) [22]


> Piter ©   (21.01.08 20:20) [12]
> Использовать системный менеджер памяти специально для таких
> случаев. См. CoTaskMemAlloc, CoTaskMemFree.
>
> а чем плох VirtualAlloc / VirtualFree?

Специально этот вопрос не исследовал, но по косвенным данным получается, что CoTaskMemAlloc/Free оптимизирован для частого выделения и освобождения относительно небольших блоков памяти, что, скорее всего, больше подходит для вашего случая.


 
Юрий Зотов ©   (2008-01-22 09:07) [23]

Как вариант - ввести в интерфейс функцию ядра, которая ведает перераспределением памяти. Получится такая схема: ядро выделяет память, передает плагину ее адрес и размер; если надо перераспределить - плагин дергает функцию ядра; освобождает память тоже ядро.


 
DiamondShark ©   (2008-01-22 11:05) [24]

Передавать плагину интерфейс менеджера памяти.
В виде IMalloc, например.


 
DiamondShark ©   (2008-01-22 11:06) [25]


> рантайтм-пакеты - это рулез.

И прощай разработка плагинов не на Дельфи той же версии.


 
jack128_   (2008-01-22 14:02) [26]

Собствено вариант один. Должен быть единый менеджер памяти. Где он будет реализован, в плагине - или ядре - не важно.
Ну например такой вариант:
//ядро:
ResultPtr := PlugIn.CallBack(Ptr, Size);
try
 // Обработка данных, полученных от плагина.
finally
 PlugIn.FreeMem(ResultPtr);
end;


 
Семеныч   (2008-01-22 14:33) [27]

> jack128_   (22.01.08 14:02) [26]

>  Где он будет реализован, в плагине - или ядре - не важно.

В каждом плагине или в одном ядре. Разница есть.


 
jack128_   (2008-01-22 14:41) [28]


> В каждом плагине или в одном ядре. Разница есть.

Хе. Задача имеет решение. Всё остальное - не важно ;-)


 
Черный Шаман   (2008-01-22 17:40) [29]


> Юрий Зотов ©   (22.01.08 09:07) [23]
>
> Как вариант - ввести в интерфейс функцию ядра, которая ведает
> перераспределением памяти. Получится такая схема: ядро выделяет
> память, передает плагину ее адрес и размер; если надо перераспределить
> - плагин дергает функцию ядра; освобождает память тоже ядро.


А если при инициализации плагина передавать в него адреса процедур главного модуля по выделению и освобождению памяти. В любом случае при подключении к процессу нужно инициализировать более-менее сложную dll, тоесть предусмотреть процедуру Init.


 
Игорь Шевченко ©   (2008-01-22 17:45) [30]

А вот MS пользует HeapAlloc/HeapFree. И радуется.


 
Черный Шаман   (2008-01-22 17:52) [31]


> Игорь Шевченко ©   (22.01.08 17:45) [30]
>
> А вот MS пользует HeapAlloc/HeapFree. И радуется.


Осталось узнать пользуется ли ими Delphi? :)


 
jack128_   (2008-01-22 17:59) [32]


> Осталось узнать пользуется ли ими Delphi? :)

пользуется. См ShareMem


 
ketmar ©   (2008-01-22 18:10) [33]

>[30] Игорь Шевченко ©(22.01.08 17:45)
то-то DLL, слинкованые с разными версиями msvcrt.dll так чудно работают, когда в одной делаешь malloc(), а в другой free()…


 
Piter ©   (2008-01-22 19:50) [34]

Игорь Шевченко ©   (22.01.08 17:45) [30]
А вот MS пользует HeapAlloc/HeapFree. И радуется


а чем это лучше VirtualAlloc или CoTaskMemAlloc?


 
Sergey Masloff   (2008-01-22 20:58) [35]

DiamondShark ©   (22.01.08 11:05) [24]
>Передавать плагину интерфейс менеджера памяти.
>В виде IMalloc, например.
А IMalloc самому реализовать? Если нет и просто использовать CoGetMalloc то какой смысл если CoTaskMemXXX это ж то же самое только одним вызовом.


 
guav ©   (2008-01-22 21:07) [36]

> [34] Piter ©   (22.01.08 19:50)

VirtualAlloc вообще не для этого. Она выделяет страницы виртуальной памяти.
Для выделения небольшого буфера для данных лучше Heap функции.


 
Игорь Шевченко ©   (2008-01-23 10:20) [37]

ketmar ©   (22.01.08 18:10) [33]


> то-то DLL, слинкованые с разными версиями msvcrt.dll так
> чудно работают, когда в одной делаешь malloc(), а в другой
> free()…


Ты читать умеешь, дружище ? Где ты в моем посте увидел msvcrt ? Или очень хочется пообщаться ? :)


 
Игорь Шевченко ©   (2008-01-23 10:24) [38]

Piter ©   (22.01.08 19:50) [34]

Чем лучше VirtualAlloc - Heap-функции оптимизированы под работу с мелкими областями памяти, кроме того, в Heap-функциях встроена сериализация при многопоточном доступе к одной и той же куче, кроме того, возможность работы с приватными кучами, которые не затрагивают выделение/освобождение памяти в других кучах, и т.д.
Чем лучше CoTaskMemAlloc - убирание лишней прослойки в виде ole.dll между приложением и kernel32 (ntdll)


 
DiamondShark ©   (2008-01-23 11:15) [39]


> Sergey Masloff   (22.01.08 20:58) [35]
> DiamondShark ©   (22.01.08 11:05) [24]
> >Передавать плагину интерфейс менеджера памяти.
> >В виде IMalloc, например.
> А IMalloc самому реализовать?

А как больше нравится, хочется и подходит под задачу.
Можно и результат CoGetMalloc вернуть, а можно и сделать обёртку над борландовским менеджером, можно свой менеджер написать.
Главное в том, что плагины будут иметь стандартный интерфейс.



Страницы: 1 вся ветка

Форум: "Прочее";
Текущий архив: 2008.02.24;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.55 MB
Время: 0.043 c
6-1181112499
Сергей Колесник
2007-06-06 10:48
2008.02.24
UDP перехватчик


15-1201059535
Slider007
2008-01-23 06:38
2008.02.24
С днем рождения ! 23 января 2008 среда


2-1201436104
kast
2008-01-27 15:15
2008.02.24
Поиск нескольких позиций в бд


15-1200719316
max
2008-01-19 08:08
2008.02.24
TASM32 v5.0


15-1201244935
oldman
2008-01-25 10:08
2008.02.24
Татьянин день





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский