Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "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
3-34707
Levan Varshanidze
2003-05-23 09:49
2003.06.12
Глюк с Quickreport


3-34725
Andrey__
2003-05-22 11:13
2003.06.12
Подскажите как обойти глюк в фильтрации...


8-34935
Дмитрий К.К.
2003-03-02 18:38
2003.06.12
Semi-transparent TBitmap


14-35014
b_baranov
2003-05-26 17:21
2003.06.12
Пакеты Erwin, xCase, RoboCase


1-34844
alvr
2003-05-30 15:23
2003.06.12
Как получить адрес почтового ящика по умолчанию из MS Outlook ?





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский