![]() |
|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
|||
|
|||
![]() Добрый день!
По производственной необходимости возникла следующая потребность: Есть основная прога, написанная на Delphi. Есть длл, написанная на Delphi Есть внешняя программа, подключающая длл. Необходимо, чтобы при вызове функции длл из внешней программы, эта длл вызывала функции программы. Если бы длл подключала основная прога, то решение было бы простым: предать в длл указатели на функции и процедуры основной проги. Можно ли как-то в длл, подключенную внешней прогой, передать указатели на функции основной проги. Спасибо! |
#2
|
||||
|
||||
![]() Каждая программа работает в своем виртуальном адресном пространстве. Поэтому заставить одну программу вызывать функции другой не так просто: в виртуальной памяти 1й проги функций 2й попросту нет.
Если DLL пишется самостоятельно, можно заставть ее отправлять сообщения окну основной проги (через SendMessage), а основную прогу на них реагировать должным образом. Для этих целей хорошо подходят сообщения с номерами WM_USER и далее. Обратную связь можно реализовать также: в ДЛЛ создать невидимое окно, и через него отправлять результат. Иначе решения будут сложнее. Например, скопировать код нужных функций в память другого процесса (через WriteProcessMemory) и вызывать их там, дописав в DLL-ку адреса скопированных функций. Но этот способ очень труден, поскольку в копируемых функциях нельзя использовать относительные адреса для работы с глобальными переменными и вызова других функций (поскольку глобальных переменных основной проги в новой вирт. памяти нет, а функции может понадобиться копировать в разные места памяти), и с абсолютными надо быть предельно осторожным (нужно релоцировать). Можно фактически использовать только относительные адреса внутри одной функции, об адресах других (включая WinAPI) узнавать уже внутри нового адресного пространства. jmp $ ; Happy End! The Cake Is A Lie. Последний раз редактировалось Bargest, 10.03.2012 в 16:25. |
#3
|
|||
|
|||
![]() спасибо
начал делать и наткнулся на ошибку в теле основной проги: const MY_MESSAGE = WM_USER + 4242; procedure MessageReceiver(var msg: TMessage); message MY_MESSAGE; procedure TMainMTCForm.MessageReceiver(var msg: TMessage); var txt: PChar; begin txt := PChar(msg.lParam); msg.Result := 1; ShowMessage(txt); end; в теле дллки: const MY_MESSAGE = WM_USER + 4242; var h:HWND; txt: string; h := findwindow('TMainMTCForm', nil); if h<>0 then begin //setwindowtext(h,'Окно By me') txt := 'Hello World'; SendMessage(h, MY_MESSAGE, 0, DWORD(PChar(txt))); end else ShowMessage('fail'); выдает ошибку access violation. при этом, если вместо SendMessage использую откомментированный setwindowtext, все работает. |
#4
|
||||
|
||||
![]() 1) Лучше все-таки WM_USER, WM_USER+1, +2,...
2) Строки в делфи - указатели на строки. При приеме будет ошибка, потому что по передаваемому адресу (а передается таким образом именно адрес) ничего не лежит. Так что отправка строки превращается в ад. Для этих целей можно попробовать WM_COPYDATA (у меня в свое время не получилось), либо выделить в памяти главного процесса удаленно нужное число байт, скопировать туда строку (с нулем на конце) и передать адрес через SendMessage. Пока что для теста лучше отправлять просто числа. Отправлять прямо в сообщении можно до 8 байт (4 в wparam, 4 в lparam). jmp $ ; Happy End! The Cake Is A Lie. Последний раз редактировалось Bargest, 11.03.2012 в 02:02. |
#5
|
|||
|
|||
![]() с числами все работает!
Спасибо! |
#6
|
||||
|
||||
![]() Цитата:
Да, маленькое замечание. При использовании PostMessage возможна потеря передаваемых данных. Цитата:
Je venus de nulle part 55.026263 с.ш., 73.397636 в.д. Последний раз редактировалось angvelem, 11.03.2012 в 02:15. |
#7
|
||||
|
||||
![]() ДЛЛ и обработчик сообщений окна в разных адресных пространствах. Указатель ничего не даст. Надо все равно копировать и содержимое "ручками".
Если ж речь про WM_CopyData - может быть, я так и не понял толком, как с ней работать, когда пытался. Тогда нашел решение проще для своей задачи. Или я чего-то не понимаю. jmp $ ; Happy End! The Cake Is A Lie. Последний раз редактировалось Bargest, 11.03.2012 в 02:17. |