Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.02.24;
Скачать: CL | DM;

Вниз

Передача данных в 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;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.014 c
15-1200760437
cartman315
2008-01-19 19:33
2008.02.24
Delphi и flash.ocx


2-1201901798
Бэтман
2008-02-02 00:36
2008.02.24
Дата рождения


15-1200828041
Parus
2008-01-20 14:20
2008.02.24
PHP and mod_layout (help)


15-1200851799
Alex_xelA
2008-01-20 20:56
2008.02.24
Модель предметной области


2-1201937189
Urvin
2008-02-02 10:26
2008.02.24
Размер плюсиков в TTreeView