Форум по Delphi программированию



Вернуться   Форум по Delphi программированию > Все о Delphi > Программа и интерфейс
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #31  
Старый 05.11.2012, 11:18
helgboy helgboy вне форума
Прохожий
 
Регистрация: 30.10.2012
Сообщения: 33
Репутация: 10
По умолчанию

Да в том то и дело что мне не надо тащить в dll переменные из exe , пусть они там и остаются, там и считаются!
Мне в dll надо вызвать функцию из exe. в процедурах описанных в самом exe я могу указать какие угодно параметры а в dll я не хочу их тащить....
Ответить с цитированием
  #32  
Старый 05.11.2012, 11:33
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от helgboy
Да в том то и дело что мне не надо тащить в dll переменные из exe , пусть они там и остаются, там и считаются!
Так в том то и дело, что когда ты подключаешь к dll-ке тот же модуль который подключаешь к exe-шнику (т.е. EXE_Unit1.pas), ты тем самым создаёшь в dll-ещё один набор переменных перечисленных в этом модуле. Т.е. переменных Num у тебя будет 2 штуки - одна в экзешнике другая в дллке. И функций summa у тебя будет 2 штуки - одна в экзешнике другая в дллке. И та функция summa которая находится в экзешнике будет работать с той переменной Num которая тоже в экзешнике, а та функция summa которая находится в дллке будт работать с той переменной Num которая тоже в дллке. Другими словами если в дллке изменилась переменная Num, то в экзешнике одноимённая переменная совершенно не изменится, потому, что это совершенно другая переменная, хоть и называется также.
Цитата:
Сообщение от helgboy
Мне в dll надо вызвать функцию из exe. в процедурах описанных в самом exe я могу указать какие угодно параметры а в dll я не хочу их тащить....
Тебе же YVitaliy написал, что для этого тебе нужно передать через параметр из экзешника в дллку указатель на функцию которая находится в экзешнике.
Ответить с цитированием
  #33  
Старый 06.11.2012, 12:58
Аватар для YVitaliy
YVitaliy YVitaliy вне форума
Местный
 
Регистрация: 14.12.2011
Сообщения: 481
Версия Delphi: Borland Delphi7
Репутация: 17
По умолчанию

Вот пример вызова через указатель (на основе твоего примера). Здесь я вызываю процедуру с параметром, но можно и без параметров.
Вложения
Тип файла: rar TestDll.rar (3.4 Кбайт, 5 просмотров)
Ответить с цитированием
  #34  
Старый 07.11.2012, 20:49
helgboy helgboy вне форума
Прохожий
 
Регистрация: 30.10.2012
Сообщения: 33
Репутация: 10
По умолчанию

Я наверно уже надоел, надеюсь задаю последний вопрос как правильно передать указатель в параметрах запущенной ловушки в dll вот код:
Код:
procedure RunStopHook(State : Boolean;nx:pointer) export; stdcall;
  begin
    if State=true then
    begin
      SysHook := SetWindowsHookEx(WH_GETMESSAGE,
            @SysMsgProc, HInstance, 0);
// здесь nx содержит правильный адрес функции используемой в exe
    end
    else// 
    begin
      UnhookWindowsHookEx(SysHook);
      SysHook := 0;
    end;
  end;
  exports RunStopHook;

function SysMsgProc(code : integer; wParam : word;
 lParam : longint) : longint; stdcall;

begin
 CallNextHookEx(SysHook, Code, wParam, lParam);
 if code = HC_ACTION then
 begin
   Wnd := TMsg(Pointer(lParam)^).hwnd;
  
    if TMsg(Pointer(lParam)^).message =WM_KEYDOWN then  
    case (TMsg(Pointer(lParam)^).wParam) of
    37:   begin
            if left1=0 then left1:=GetTickCount(); 
            if (GetTickCount()-left1)>=time then begin  left(); end
          end;
  
    end;

 
 end;
end;



procedure left();
begin
showmessage('  Nx='+inttostr(Integer(nx^)));
end;



Здесь при запуски ловушки клавиатуры при нажатии клавишы "37" дожны вызваться процедура left(); и внутри выдать сообщение (например) с адресом функции.
Я пытался в SysMsgProc вставить в качестве четвертого аргумента nx: pointer выдает ошибку... Прошу поправьте мой код.

Последний раз редактировалось helgboy, 07.11.2012 в 21:04.
Ответить с цитированием
  #35  
Старый 07.11.2012, 21:16
Аватар для YVitaliy
YVitaliy YVitaliy вне форума
Местный
 
Регистрация: 14.12.2011
Сообщения: 481
Версия Delphi: Borland Delphi7
Репутация: 17
По умолчанию

Попробуй обьяви nx как глобальную переменную для Dll, или попробуй сохранять не указатель, а процедуру.
Код:
var proc:procedure();
begin
...........................................
procedure RunStopHook(State : Boolean;nx:pointer) export; stdcall;
  begin
    if State=true then
    begin
      SysHook := SetWindowsHookEx(WH_GETMESSAGE,
            @SysMsgProc, HInstance, 0);
          if nx<>nil then
           @proc:=nx;//запоминаем процедуру (в nx адрес процедуры left()?)
    end
    else// 
    begin
      UnhookWindowsHookEx(SysHook);
      SysHook := 0;
    end;
  end;
.....................................................................
function SysMsgProc(code : integer; wParam : word;
 lParam : longint) : longint; stdcall;
 
begin
 CallNextHookEx(SysHook, Code, wParam, lParam);
 if code = HC_ACTION then
 begin
   Wnd := TMsg(Pointer(lParam)^).hwnd;
   
    if TMsg(Pointer(lParam)^).message =WM_KEYDOWN then 
    case (TMsg(Pointer(lParam)^).wParam) of
    37:   begin
            if left1=0 then left1:=GetTickCount(); 
            if (GetTickCount()-left1)>=time then 
          begin  
             proc(); //вызываем процедуру
          end
          end;
   
    end;
 
  
 end;
end;


end;
Ответить с цитированием
  #36  
Старый 07.11.2012, 21:59
helgboy helgboy вне форума
Прохожий
 
Регистрация: 30.10.2012
Сообщения: 33
Репутация: 10
По умолчанию

да нет же , не годится в nx хранится адрес процедуры из exe. nx трогать нельзя.
Мне надо строго при нажатии клавиши 37 запустить функцию left и в ней использовать nx
Ответить с цитированием
  #37  
Старый 07.11.2012, 22:15
Аватар для YVitaliy
YVitaliy YVitaliy вне форума
Местный
 
Регистрация: 14.12.2011
Сообщения: 481
Версия Delphi: Borland Delphi7
Репутация: 17
По умолчанию

А кто этот указатель трогает
Чтобы его использовать, его нужно куда-то сохранить, так как через параметр процедуры SysMsgProc его передать нельзя, то я его передаю через
Код:
var proc:procedure();
. Вот эта
Цитата:
proc
и должна быть такого же типа, как и процедура в exe. А сохраняю ее
Код:
@proc:=nx;
, указатель nx остается таким, каким и был.
Можешь вместо
Код:
var proc:procedure();
объявить
Код:
var nx1:pointer;
и клонировать указатель
Код:
nx1:=nx;
и в процедуре left использовать nx1 вместо nx - ссылаться он будет туда же, что и nx.
Ответить с цитированием
  #38  
Старый 08.11.2012, 01:14
helgboy helgboy вне форума
Прохожий
 
Регистрация: 30.10.2012
Сообщения: 33
Репутация: 10
По умолчанию

все я въехал, спасибо почти получилось.
В exe при прорисовки формы присвоил указателю nx адрес нужной мне процедуры :
Код:
var
..............
procedure perebor();
........

nx:=@perebor;
.........
Далее в определенный момент запустил ловушку в dll и одновременно передал в dll указатель nx и присвоил его новому указателю объявленному в dll nx1 . Тут все отлично.

Далее при нажатии клавиши "37" отрабатывает процедура опять в exe

Код:
procedure keyctrl(nx1:pointer)
var i:integer;
procedure rezultat();
begin
@rezultat:=nx1; { вот здесь то и выбивает ошибку [Error] main.pas(14): Left side cannot be assigned to}
end;

Почему когда я пишу такой код @rezultat:=nx1; выбивает ошибку ?
Ответить с цитированием
  #39  
Старый 08.11.2012, 01:25
Аватар для YVitaliy
YVitaliy YVitaliy вне форума
Местный
 
Регистрация: 14.12.2011
Сообщения: 481
Версия Delphi: Borland Delphi7
Репутация: 17
По умолчанию

обьявляй в разделе var resultatrocedure();
А потом после begin'а (для проседуры keyctrl) -
Код:
@rezultat:=nx1;
а то выходит, что ты уже реализуешь эту функцию, когда тебе нужен только указатель на готовую в EXE.
Код:
procedure keyctrl(nx1:pointer)
var i:integer;
rezultat :procedure() ;
begin
@rezultat:=nx1; { вот так не должно выводить ошибку}
end;

ЗЫ интересные эффекты со смайликами.
Ответить с цитированием
  #40  
Старый 08.11.2012, 15:55
helgboy helgboy вне форума
Прохожий
 
Регистрация: 30.10.2012
Сообщения: 33
Репутация: 10
По умолчанию

Ну чтож почти все получилось. Получил правильный адрес в конечной процедуре keyctrl в exe .
Остался небольшой баг если начальная требуемая процедура perebor(); была объявлена так :
Код:
type 
Tvideodriver = class(TForm)
procedure leftClick(Sender: TObject);
end;
procedure perebor();// адрес этой процедуры передается в dll и обратно
var
......
implementation
procedure keyctrl(nx1:pointer)
var i:integer;
rezultat :procedure() ;
begin
@rezultat:=nx1;// адрес процедуры perebor()
end;
......
то все отлично работает , а если присвоить perebor к классу главной формы то во время выполнения программы вылетает ошибка
приверно вот так:
Код:
type 
Tvideodriver = class(TForm)
procedure leftClick(Sender: TObject);
procedure perebor(Sender: TObject);// адрес этой процедуры передается в dll и обратно
end;

var
......
implementation
procedure keyctrl(nx1:pointer)
var i:integer;
rezultat :procedure() ;
begin
@rezultat:=nx1;// адрес процедуры perebor()
end;
......
При чем ошибка появляется именно в момент загрузки dll.
Я правильно понял как говорилось где то выше , что это обойти никак нельзя?
Ответить с цитированием
  #41  
Старый 08.11.2012, 16:17
icWasya icWasya вне форума
Местный
 
Регистрация: 09.11.2010
Сообщения: 499
Репутация: 10
По умолчанию

а если присвоить perebor к классу , то тип процедуры изменится
с
Код:
Type TProc = Procedure();
на
Код:
Type TProc = Procedure() of object;
и указатель на такую процедуру будет занимать ДВА поинтера и работать с этим придётся по другому, например так
----EXE------
Код:
type Tvideodriver = class(TForm)
 procedure leftClick(Sender: TObject); 
 procedure perebor(Sender: TObject);// адрес этой процедуры передается в 
dll и обратно end; 

......

procedure keyctrl(nx1:TNotifyEvent); external 'MyDLL.DLL'; 
implementation

procedure Tvideodriver.Button1Click(Sender:TObject);
begin
   keyctrl(perebor); //<<== заметь, без @ и без скобок 
end;
------ DLL -----
procedure keyctrl(nx1:TNotifyEvent);
var
rezultat :TNotifyEvent;
begin

rezultat := nx1; //<<== заметь, без @ и без скобок

...
end;
Ответить с цитированием
  #42  
Старый 08.11.2012, 17:21
helgboy helgboy вне форума
Прохожий
 
Регистрация: 30.10.2012
Сообщения: 33
Репутация: 10
По умолчанию

icWasya , спасибо за пример но все не так, вы наверно не читали предыдущие сообщения и многое путаете.
Уточняю должно быть так и только так :
-В exe берется поинтер на процедуру perebor()
- отправляется в ловушку в dll
- в dll при срабатывании процедуры left() открывается процедура keyctrl уже в exe
- далее keyctrl запускает изначальную нужную perebor() присваивая адрес на нее.
Но тут то и облом... вот тоже самое в коде
----- EXE----
Код:
type
Tmain = class(TForm)
procedure perebor(Sender: TObject);// адрес этой процедуры передается в dll и обратно
end;
procedure RunStopHook(State : Boolean;pointperebor:pointer) stdcall; external 'hookkey.dll'; 
var
pointperebor: pointer;
......
implementation
procedure keyctrl(x:pointer)
var i:integer;
rezultat :procedure() ;
begin
@rezultat:=x;// адрес процедуры perebor()
rezultat();// вызов процедуры perebor
end;
.....
pointperebor:=@Tmain.perebor;
.....
begin
RunHook(true,pointperebor)// передаем в dll адрес на процедуру perebor
end;

......

------DLL------
Код:
procedure RunStopHook(State : Boolean;pointperebor:pointer) export; stdcall;
      begin
          if State=true then
          begin
          // Запускаем ловушку.
          SysHook := SetWindowsHookEx(WH_GETMESSAGE,
            @SysMsgProc, HInstance, 0);
          x:=pointperebor;
          left();
        end
        
      end;
procedure left(x:pointer);
    begin
    keyctrl(x);
    end;
Здесь и вопрос как сделать это
@rezultat:=x;// адрес процедуры perebor()
rezultat();// вызов процедуры perebor
если perebor присвоен к классу формы.
Ошибка "access violation at address" - я так полагаю он пытается запустить процедуру которой уже нет, обойти это никак нельзя? (Приэтом у меня подключен модуль fastsharemem)

Последний раз редактировалось helgboy, 08.11.2012 в 17:41.
Ответить с цитированием
  #43  
Старый 08.11.2012, 18:30
Аватар для YVitaliy
YVitaliy YVitaliy вне форума
Местный
 
Регистрация: 14.12.2011
Сообщения: 481
Версия Delphi: Borland Delphi7
Репутация: 17
По умолчанию

Во-первых, как ты запускаешь
Цитата:
left()
без параметра, если там должен передаваться указатель (напр. left(X)).
Во-вторых, если указатель на метод обьекта, то нужно делать как пишет icWasya - типа так:
Код:
type
Tmain = class(TForm)
procedure perebor(Sender: TObject);// адрес этой процедуры передается в dll и обратно
end;
procedure RunStopHook(State : Boolean;pointperebor:pointer) stdcall; external 'hookkey.dll'; 
var
pointperebor: pointer;
pointproc:procedure() of object;
......
implementation
procedure keyctrl(x:pointer)
var i:integer;
rezultat :procedure() of object;
begin
@rezultat:=x;// адрес процедуры perebor()
rezultat();// вызов процедуры perebor
end;
.....
pointproc:=Tmain.perebor;
pointperebor:=@pointproc;
.....
begin
RunHook(true,pointperebor)// передаем в dll адрес на процедуру perebor
end;
 
......
почему-то нужно указатель запоминать через доп. переменную (pointproc: procedure() of object иначе не получается.
Код:
procedure RunStopHook(State : Boolean;pointperebor:pointer) export; stdcall;
      begin
          if State=true then
          begin
          // Запускаем ловушку.
          SysHook := SetWindowsHookEx(WH_GETMESSAGE,
            @SysMsgProc, HInstance, 0);
          x:=pointperebor;
          left({здесь должен быть какой-то указатель, напр. "Х"});
        end
         
      end;
procedure left(x:pointer);
    begin
    keyctrl(x);
    end;
Ответить с цитированием
  #44  
Старый 08.11.2012, 23:27
helgboy helgboy вне форума
Прохожий
 
Регистрация: 30.10.2012
Сообщения: 33
Репутация: 10
По умолчанию

pointproc:=Tmain.perebor; - здесь возникает ошибка
[Error] mainprogram.pas(633): Incompatible types: 'Parameter lists differ'
Ответить с цитированием
  #45  
Старый 08.11.2012, 23:48
Аватар для YVitaliy
YVitaliy YVitaliy вне форума
Местный
 
Регистрация: 14.12.2011
Сообщения: 481
Версия Delphi: Borland Delphi7
Репутация: 17
По умолчанию

Цитата:
Сообщение от helgboy
pointproc:=Tmain.perebor; - здесь возникает ошибка
[Error] mainprogram.pas(633): Incompatible types: 'Parameter lists differ'
Ну, это я ошибся - при объявлении pointproc нужно указать такие же параметры, как и в perebor:
Код:
var
pointperebor: pointer;
pointproc:procedure(Sender:TObject) of object;//вот здесь
Но ты и сам должен был догадаться.

ЗЫ Хотя зачем в perebor этот Sender:TObject не понимаю.
Ответить с цитированием
Ответ



Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 22:14.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter   Ссылка на Telegram