Форум: "WinAPI";
Текущий архив: 2003.06.12;
Скачать: [xml.tar.bz2];
ВнизСвязь с DLL Найти похожие ветки
← →
Gayrus (2003-04-10 03:10) [0]Пытаюсь наладить связь 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;
Здесь я не привожу остальную часть ловушки, но не работает точно где-то здесь.
← →
Игорь Шевченко (2003-04-10 09:31) [1]
@FRunHook :=nil;
@FRunHook :=GetProcAddress(hDLL,"RunHook");
@P:=nil;
@P:=GetProcAddress(HInstance,"DoMsgFromHook");
А зачем по два раза ? :-)))
← →
Cobalt (2003-04-10 13:01) [2]Если вы устанавливаете ловушку с помощью "функции из ДЛЛ", то зачем ей передавать в качестве параметра адрес процедуры-ловушки? Проще (избежать ошибок) указывая функции "внутренний идентификатор" функции-ловушки
Совсем непонятно, что делает RunHook - что еще за длина? На первый взгляд (извиняюсь) - бред какой-то :(
← →
Gayrus (2003-04-10 16:37) [3]Пояснию: в качестве параметра (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 19:01) [4]То есть, ты хочешь ставить несколько ловушек? А ловушки будут из той-же ДЛЛ-ки?
Ну-ка, объясняй все подробно!
З.Ы. Телепатов тут еще нет (а если и придут - то скоро уйдут, судя по некоторым вопросам)
← →
Gayrus (2003-04-11 03:34) [5]Несколько программ передают в DLL адреса своих процедур, DLL их сохраняет в aHookProc, а потом всем передаёт сообщения по этим адресам процедур из ОДНОЙ ловушки, по моему ничего сложного здесь нет, и не надо быть телепатом :)
Только и осталось передать эти самые адреса.
← →
nikolai (2003-04-11 11:10) [6]Может я что-то недопонимаю но:
>aHookProc : Array of THookProc;
будет располагаться в каждом модуле, загружающем библиотеку, в адресном пр-ве этого процесса (т.е. если в процессе RunHook вызывается 1 раз, то сколко бы процессов не загружало библ. в каждом процессе LengHP будет =1). Может где-то рядом и ответ почему ядро ошибку выдает.
← →
Cobalt (2003-04-11 12:11) [7]Храни межпроцессные данные в одном месте - между процессами (Memory mapped files)
И вообще, еще разок прочитай статью про хуки, и нарисуй себе схему взаимодействия процессов и ДЛЛ-ки с учетом межпроцессности.
← →
nikkie (2003-04-11 13:55) [8]>exports DoMsgFromHook;
exe не эксопртирует функции
>@P:=GetProcAddress(HInstance,"DoMsgFromHook");
The GetProcAddress function returns the address of the specified exported dynamic-link library (DLL) function.
пройдись дебаггероми посмотри на какой строчке вылетает ошибка
← →
Игорь Шевченко (2003-04-11 14:13) [9]>exe не эксопртирует функции
Разве ?
← →
Nikolai (2003-04-11 15:56) [10]Отображаемые в память Файлы в данном случае не помогут, т.к. данными явл. адреса функций конкретных, а т.к. ловушка системная то она будет подгружаться ко ВСЕМ (? именно это нужно?) процессам и пытаться передать управление точке, скажем 0xGGGGGGG что в адресном пространстве другого процесса полная чушь.
Если надо реагировать скажем на события мыши/клавиатуры направляемые всем процессам тогда конечно без системной ловушки не обойтись но вот запускать код чужого процесса передачей адреса не получиться. По моему скромному разумению, лучше организовать тот самый файл проецируемый в память плюс не забыть про межпроцессную синхронизацию для обмена данными, а в качестве механизма запускающего процедуры использовать объекты синхронизации доступные на межпроцессном уровне (Mutex, Event) в паре с функциями ожидания (WaitFor...)
← →
nikkie (2003-04-11 16:14) [11]>Игорь Шевченко
export написать в коде программы можно. Я посмотрел в DependencyWalker - действительно, функция появляется в списке экспортируемых функций. Можно ли эту функцию вызвать штатными средствами (LoadLibrary, GetProcAddress), я не знаю, сейчас нет времени проверять, вообще-то сомнительно - у exe и dll по идее разные entry point. В любом случае, это недокументированный вариант и смысла так делать я не вижу.
Поскольку установка hook-a в коде отсутствует, то проблемы разных адресных пространств здесь не причем (пока - когда будет ставиться хук, вот тут они и полезут). Скорее всего,
@P:=GetProcAddress(HInstance,"DoMsgFromHook");
возвращает NULL.
← →
Cobalt (2003-04-11 16:26) [12]2 Gayrus ©
Совершенно согласен с Nikolai
В момент события ловушка будет находиться в АП одного процесса, а сообщить об этом - разным процессам. С помощью адресов тут ничего не получится. Нужно работать с событиями(т.к. несколько процессов могут ждать наступления одного события, подробнее см. Event Objects).
← →
AME (2003-04-11 17:12) [13]В своей программе делал так:
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
← →
AME (2003-04-11 17:13) [14]Sorry!
var aHookProc : Array of TSNproc;
Поспешишь, людей насмешишь.
← →
Gayrus (2003-04-12 10:23) [15]2 AME BIG 10x
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2003.06.12;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.01 c