Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Связь с DLL [D5]


Gayrus ©   (2003-04-10 03:10:00) 

Пытаюсь наладить связь DLL с приложением, но выдаётся ошибка "Праграмма Project1 вызвала ошибку в KERNEL32.DLL..." вот код:

type THookProc=Procedure(var Msg:TMsg);

код DLL:

var LengHP: Integer=0;
aHookProc : Array of THookProc;

function RunHook(ToProc:THookProc):Integer;export;stdcall;
begin
Result:=-1;
If @ToProc=nil then Exit;
try
LengHP:=Length(aHookProc)+1;
SetLength(aHookProc,LengHP);
except
Dec(LengHP);
Exit;
end;
try
@aHookProc[LengHP-1]:=nil;
@aHookProc[LengHP-1]:=@ToProc;
except
Exit;
end;
Result:=LengHP-1;
// я убрал даже запуск ловушки, но всё равно не работает.
end;

exports RunHook;


Код программы:

var Form1: TForm1;
hDLL:THandle;
FRunHook :Function(ToProc:THookProc):Integer;
FHookIndex:Integer=-1;

Procedure DoMsgFromHook(var msg:TMsg);export;stdcall;
begin
Form1.Edit2.Text:=IntToStr(msg.message);
end;
exports DoMsgFromHook;

procedure TForm1.Button2Click(Sender: TObject);
var P:THookProc;
begin
hDLL:=LoadLibrary("HookLib.dll");
If hDLL>HINSTANCE_ERROR then try
@FRunHook :=nil;
@FRunHook :=GetProcAddress(hDLL,"RunHook");
@P:=nil;
@P:=GetProcAddress(HInstance,"DoMsgFromHook");
FHookIndex:=FRunHook(P);
Button3.Enabled:=( FHookIndex>(-1) );
Button2.Enabled:=not Button3.Enabled;
except
// Как уже было написано программа выдаёт ошибку
Application.Terminate; // и здесь закрывается
// иначе Windows вообще виснет :)
end;
end;


Здесь я не привожу остальную часть ловушки, но не работает точно где-то здесь.


Gayrus   (2003-04-12 10:23:00) [1]

2 AME BIG 10x


AME   (2003-04-11 17:13:00) [2]

Sorry!
var aHookProc : Array of TSNproc;
Поспешишь, людей насмешишь.


AME   (2003-04-11 17:12:00) [3]

В своей программе делал так:
FRunHook :Function(ToProc:TFarProc):Integer;

FHookIndex:=FRunHook(@DoMsgFromHook);//вызов DLL
*************************************************
В DLL
type TSNproc = procedure(var msg:TMsg);stdcall;

var aHookProc : Array of TFarProc;

@aHookProc[LengHP-1]:=ToProc;


aHookProc(Msg);//Call


Cobalt   (2003-04-11 16:26:00) [4]

2 Gayrus ©
Совершенно согласен с Nikolai
В момент события ловушка будет находиться в АП одного процесса, а сообщить об этом - разным процессам. С помощью адресов тут ничего не получится. Нужно работать с событиями(т.к. несколько процессов могут ждать наступления одного события, подробнее см. Event Objects).


nikkie   (2003-04-11 16:14:00) [5]

>Игорь Шевченко
export написать в коде программы можно. Я посмотрел в DependencyWalker - действительно, функция появляется в списке экспортируемых функций. Можно ли эту функцию вызвать штатными средствами (LoadLibrary, GetProcAddress), я не знаю, сейчас нет времени проверять, вообще-то сомнительно - у exe и dll по идее разные entry point. В любом случае, это недокументированный вариант и смысла так делать я не вижу.

Поскольку установка hook-a в коде отсутствует, то проблемы разных адресных пространств здесь не причем (пока - когда будет ставиться хук, вот тут они и полезут). Скорее всего,
@P:=GetProcAddress(HInstance,"DoMsgFromHook");
возвращает NULL.


Nikolai   (2003-04-11 15:56:00) [6]

Отображаемые в память Файлы в данном случае не помогут, т.к. данными явл. адреса функций конкретных, а т.к. ловушка системная то она будет подгружаться ко ВСЕМ (? именно это нужно?) процессам и пытаться передать управление точке, скажем 0xGGGGGGG что в адресном пространстве другого процесса полная чушь.
Если надо реагировать скажем на события мыши/клавиатуры направляемые всем процессам тогда конечно без системной ловушки не обойтись но вот запускать код чужого процесса передачей адреса не получиться. По моему скромному разумению, лучше организовать тот самый файл проецируемый в память плюс не забыть про межпроцессную синхронизацию для обмена данными, а в качестве механизма запускающего процедуры использовать объекты синхронизации доступные на межпроцессном уровне (Mutex, Event) в паре с функциями ожидания (WaitFor...)


Игорь Шевченко   (2003-04-11 14:13:00) [7]

>exe не эксопртирует функции

Разве ?


nikkie   (2003-04-11 13:55:00) [8]

>exports DoMsgFromHook;
exe не эксопртирует функции

>@P:=GetProcAddress(HInstance,"DoMsgFromHook");
The GetProcAddress function returns the address of the specified exported dynamic-link library (DLL) function.

пройдись дебаггероми посмотри на какой строчке вылетает ошибка


Cobalt   (2003-04-11 12:11:00) [9]

Храни межпроцессные данные в одном месте - между процессами (Memory mapped files)
И вообще, еще разок прочитай статью про хуки, и нарисуй себе схему взаимодействия процессов и ДЛЛ-ки с учетом межпроцессности.


nikolai   (2003-04-11 11:10:00) [10]

Может я что-то недопонимаю но:
>aHookProc : Array of THookProc;
будет располагаться в каждом модуле, загружающем библиотеку, в адресном пр-ве этого процесса (т.е. если в процессе RunHook вызывается 1 раз, то сколко бы процессов не загружало библ. в каждом процессе LengHP будет =1). Может где-то рядом и ответ почему ядро ошибку выдает.


Gayrus   (2003-04-11 03:34:00) [11]

Несколько программ передают в DLL адреса своих процедур, DLL их сохраняет в aHookProc, а потом всем передаёт сообщения по этим адресам процедур из ОДНОЙ ловушки, по моему ничего сложного здесь нет, и не надо быть телепатом :)
Только и осталось передать эти самые адреса.


Cobalt   (2003-04-10 19:01:00) [12]

То есть, ты хочешь ставить несколько ловушек? А ловушки будут из той-же ДЛЛ-ки?
Ну-ка, объясняй все подробно!
З.Ы. Телепатов тут еще нет (а если и придут - то скоро уйдут, судя по некоторым вопросам)


Gayrus   (2003-04-10 16:37:00) [13]

Пояснию: в качестве параметра (P) передаётся адрес процедуры из САМОЙ ПРОГРАММЫ, а позже в DLL будет вызываться так

function SysMsgProc(code:Integer;wParam:word;LParam:LongInt):LongInt;stdcall;
var I:Integer;
mess:TMsg;
begin
try
If(Code=HC_ACTION)and(Length(aHookProc)>0)then begin
mess:=TMsg(Pointer(Lparam)^);
for I:=0 to (LengHP-1) do aHookProc[i](mess);
end;
finally
Result:=CallNextHookEx(SysHook,Code,wParam,LParam);
end;
end;

Тоесть, в aHookProc у меня храняться ссылки на процедуры в программах( несколько приложений будут использовать одну DLL). А LengHP-чтобы не вычеслять каждый раз Length(aHookProc).
А если интересно, то ещё в RunHook"e будет
If LengHP=1 then SysHook:=SetWindowsHookEx(WH_GETMESSAGE,@SysMsgProc,hInstance,0);
P.S. Если есть другой способ вызывать процедуры EXE"шника, напишите. SendMessage не предлагать!


Cobalt   (2003-04-10 13:01:00) [14]

Если вы устанавливаете ловушку с помощью "функции из ДЛЛ", то зачем ей передавать в качестве параметра адрес процедуры-ловушки? Проще (избежать ошибок) указывая функции "внутренний идентификатор" функции-ловушки
Совсем непонятно, что делает RunHook - что еще за длина? На первый взгляд (извиняюсь) - бред какой-то :(


Игорь Шевченко   (2003-04-10 09:31:00) [15]

@FRunHook :=nil;
@FRunHook :=GetProcAddress(hDLL,"RunHook");
@P:=nil;
@P:=GetProcAddress(HInstance,"DoMsgFromHook");


А зачем по два раза ? :-)))


Наверх

Титульная страница Поиск, карта сайта Написать письмо