Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.10.16;
Скачать: CL | DM;

Вниз

Передача и вызов процедуры/функции.   Найти похожие ветки 

 
Nick Denry ©   (2005-09-21 17:05) [0]

Есть такая проблема: моей программе  передают указатель на процедуру или функцию (из другой программы) и как эту самую функцию, по этому указателю вызвать (своего рода callback).

т.е. надо что-то типа call из asm или можно как-то по-другому?


 
begin...end ©   (2005-09-21 17:08) [1]

Указатель на функцию некоторой программы будет недействителен в другой программе.


 
ANB ©   (2005-09-21 17:14) [2]

Точнее : указатель на функцию из другого процесса недействителен в твоем процессе. Если программы - это модули или DLL в одном процессе - то проблем нет. Можно даже на asm не уходить - описываешь указатель на функцию (нужен прототип) и вызываешь. Если процессы разные - то дело намного серьезнее, придется писать DLL и осуществлять внедрение в AP чужого процесса. А уже во внедренном коде производить вызов коллбэка.


 
Nick Denry ©   (2005-09-21 20:08) [3]

Если программы - это модули или DLL в одном процессе - то проблем нет.

Именно так. Т.е. один из них - мой экзешник (- он передает указатель), а библиотека, должна вызвать эту функцию (библиотека - это глобальный контрол, как Мйкрософтовские кнопки (класс "BUTTON"), например).

Можно даже на asm не уходить

Вот это меня интересовало. И еще интересует, обязан ли я указывать формат вызова (например stdcall) или нет?


 
Nick Denry ©   (2005-09-21 20:11) [4]

Извиняюсь за изначально криво поставленный вопрос, ибо что указатель на функцию из другого процесса недействителен в твоем процессе мне известно, а так, как вопрос поставил то сам себе бы по ушам надавал..


 
Zeqfreed ©   (2005-09-21 20:23) [5]

Nick Denry ©   (21.09.05 20:11) [4]
Ну тебе уже ответили в [2], что нужно описать прототип ф-ции.

Например:
type
TFooProc = function(arg1, arg2 : TSomeType) : TSomeOtherType;


Там где надо вызывать ф-цию:
procedure CallFooProc(proc : TFooProc);
begin
proc(arg1, arg2);
end;


Ну и, соответственно, в основном модуле:
function FooProc(arg1, arg2 : TSomeType) : TSomeOtherType;
begin
//place your code here ;)
end;
...
CallFooProc(FooProc);


Код не проверял, но все должно быть примерно так :)


 
Nick Denry ©   (2005-09-21 21:51) [6]

Zeqfreed ©   (21.09.05 20:23) [5]

Мне не подходит такое решение.

Мне необходимо вызвать поцедуру (даже не функцию),имея на руках только указатель.

Упростим задачу до минимума:

Есть два файла - Exe и Dll.

Как я уже сказал, Dll представляет собой библиотеку с моим контролом.

У каждого экземпляра контрола есть свойиство (Prop), в который мне надо поместить указать на процедуру, содержащуюся в экзешнике, и при наступлении определнного события в контроле из библиотеки вызвать процедуру экзешника.

Нверное лучше еще задать подвопрос: как из указателя получить DWORD и обратно?


 
Zeqfreed ©   (2005-09-21 22:13) [7]

Nick Denry ©   (21.09.05 21:51) [6]
Если список параметров ф-ции не меняется во время выполнения программы, то не понимаю почему решение не подходит.


> Нверное лучше еще задать подвопрос: как из указателя
> получить DWORD и обратно?

DWORD(SomePointer) ?


 
Nick Denry ©   (2005-09-21 22:32) [8]

Zeqfreed ©   (21.09.05 22:13) [7]

А обратно?
Pointer(DWORD)?


Если список параметров ф-ции не меняется во время выполнения программы, то не понимаю почему решение не подходит.


Наверное я не понял вашего описания. Или неполучится сделать уникальный вызов для каждого контрола.

Если можно, объясните еще раз на пальцах :))

Я тоже пропробую:

Пусть в exe есть процедура:


procedure ProcedureInExe;
begin
 ShowMessage("Test");
end;


И соответственно событие, происходящее в DLL в оконной процедуре контрола:

WM_ANYMESSAGE:
                        begin
                        end;

Мне надо, что бы для каждого экземпляра контрола (т.е. окна) была установлена индивидуальная ф-ция обработки, -> как я думаю, ее адрес (указатель на нее) можно было бы разместить как Property окна, при поммощи функции SetProp - и извлеч его как GetProp, но

обе ити функци используют DWORD параметры, например:

BOOL SetProp(
   HWND hWnd, // handle of window
   LPCTSTR lpString, // atom or address of string
   HANDLE hData  // handle of data
  );

Т.е. если, в экзе я могу вызвать код, чтобы поместить туда указатель на процедуру ProcedureInExe;:

Setprop(ControlWnd, PChar("ProcedureInExe"+IntToStr(ControlID))), DWORD(@ProcedureInExe));

то что мне дальше нужно сделать со зхначением, DWORD(@ProcedureInExe), которое я извлеку с помощью функции GetProp?

Т.е. по-идее я должен в Dll

при обработки сообщения WM_ANYMESSAGE сделать следующие деййствия:
...
var
   ProcInexePointer : DWORD; // (?POINTER)
WM_ANYMESSAGE:
                        begin
                         ProcInexePointer  :=  GetProp(ctrlWnd, PChar("ProcedureInExe"+IntToStr(ControlID))));

а дальше чо-то типа
asm
   call ProcInexePointer;
end;
  end;
только этот метод почему-то не работает, и как мне в таком случае из DWORD(Pointer) всеже получить обратно Pointer?

или такое можон осуществить еще как-то?


 
Zeqfreed ©   (2005-09-21 22:50) [9]

Nick Denry ©   (21.09.05 22:32) [8]
Файл callback_type.inc:
type
TCallback = procedure();


Файл some.dpr:
library some;

uses
 Windows;

{$I callback_type.inc}  

var
Callback : TCallback;

procedure RegisterCallback(Proc : TCallback);
begin
Callback := Proc;
end;

procedure UseCallback();
begin
Callback();
end;

exports
RegisterCallback, UseCallback;

begin
end.


Файл prog.dpr:
program prog;

uses
 Windows;

{$I callback_type.inc}

procedure RegisterCallback(Proc : TCallback); external "some.dll" name "RegisterCallback";
procedure UseCallback(); external "some.dll" name "UseCallback";

procedure SomeProc();
begin
MessageBox(0, "Does it work?", "Prog", 0);
end;

begin
RegisterCallback(SomeProc);
UseCallback();
end.


Надеюсь разберешься.


 
Nick Denry ©   (2005-09-21 22:54) [10]

Надеюсь разберешься.

спасибо, постараюсь.


 
Zeqfreed ©   (2005-09-21 22:57) [11]

А, да. Я так понял тебя интересует именно хранение указателя. Тогда так:

dll:
var
Callback : Pointer;

procedure RegisterCallback(Proc : TCallback);
begin
Callback := @Proc;
end;

procedure UseCallback();
begin
TCallback(Callback);
end;



 
Nick Denry ©   (2005-09-21 23:08) [12]

Zeqfreed ©   (21.09.05 22:57) [11]

Ну вот, теперь кажется и мне понятно :))

Но не факт, буду пробовать..


 
Eraser ©   (2005-09-21 23:12) [13]


> Nick Denry ©

Может для твой задачи проще использовать серверы автоматизации COM или NET Remoting или вообще ? Зачем же велосипед изобретать?


 
Nick Denry ©   (2005-09-21 23:18) [14]

Eraser ©   (21.09.05 23:12) [13]

К сожалению у меня задача изобрести велосипед :(


 
Игорь Шевченко ©   (2005-09-21 23:23) [15]

Nick Denry ©   (21.09.05 23:18) [14]

Кулибин.

type
 TMyProc = procedure (arg: Pojnter);

procedure MyProc (arg: Pointer);
begin
 все, что надо
end;

procedure AssociateMyProcWithControl (HControl: HWND);
begin
 SetProp(HControl, PROP_ATOM, Handle(@MyProc));
end;

procedure InvokeAssociatedProc (HControl: HWND; Arg: Pointer);
var
  AMyProc: TMyProc;
begin
 @AMyProc := GetProp(HControl, PROP_ATOM);
 if Assigned(AMyProc) then
    AMyProc(Arg);
end;

В рамках одного процесса, без разницы, в EXE или в DLL.


 
Nick Denry ©   (2005-09-21 23:40) [16]

Игорь Шевченко ©   (21.09.05 23:23) [15]

Кулибин.

Дык, это не я, это у препода крыша протекла. Вынь да вылож ему (


 
Nick Denry ©   (2005-09-21 23:42) [17]

Игорь Шевченко ©   (21.09.05 23:23) [15]

Спасибо за понятный код :)

Век бы ковырялся с пойнтерами :)


 
Eraser ©   (2005-09-21 23:57) [18]


> Игорь Шевченко ©   (21.09.05 23:23) [15]
> В рамках одного процесса, без разницы, в EXE или в DLL.


Дык автор то просил (из другой программы)...


 
Игорь Шевченко ©   (2005-09-22 00:29) [19]


> Дык, это не я, это у препода крыша протекла. Вынь да вылож
> ему (


Я тебе отвечал последний раз.

LMD


 
Nick Denry ©   (2005-09-22 01:07) [20]

Игорь Шевченко ©   (22.09.05 00:29) [19]

Почему? :(

Из-за того, что это курсовая работа или я чем-то обидел?

И кстати,
@AMyProc := GetProp(HControl, PROP_ATOM);
выдает [Error] Incompatible types: "Cardinal" and "Pointer"
на самом деле надо было:
@AMyProc := Ptr(GetProp(HControl, PROP_ATOM));

Eraser ©   (21.09.05 23:57) [18]
Автор ошибся и указал об этом в  [4]


 
Nick Denry ©   (2005-09-22 01:14) [21]

Игорь Шевченко ©   (22.09.05 00:29) [19]

А препод действительно дал мне, как он сам выразился "задание повышенной сложности".

И описал задачу, которая свелась именно  такому решению, и никакого другого, он кстати, не принял.

Я хотел вместо вызова процедуры по типу callback сделать отправку сообщения родительского окну (по типу WM_COMMAND), а он сказал, чтобы был обязательно callback.

Даже если отвечаешь мне последний раз, ответь все-таки пожалуйста почему?


 
Германн ©   (2005-09-22 02:07) [22]

Оп-ля!
Хотел было посоветовать автору сабжа обратиться к ИШ приватно, т.е. по email или через его сайт.
Но обнаружил, что из анкеты Игоря - напрочь пропали все ссылки!

Это что? Новая мода? Борьба с вирусописателями?

Хорошо, что я успел скачать с сайта ИШ что хотел!


 
GanibalLector ©   (2005-09-22 02:26) [23]

2 Германн ©   (22.09.05 02:07) [22]
>Хорошо, что я успел скачать с сайта ИШ что хотел!
Пардон,конечно...но,что ж там было???


 
Германн ©   (2005-09-22 02:38) [24]

2 GanibalLector ©   (22.09.05 02:26) [23]

Там было- море, солнце, песок И т.д. и т.п. :)
И, блин, ответы на многие вопросы, которые тут, имхо, слишком частые!

Если ты их "прозевал", то увы!


 
Игорь Шевченко ©   (2005-09-22 10:42) [25]


> ответь все-таки пожалуйста почему?


потому что препод дал задание тебе, а не мне



Страницы: 1 вся ветка

Текущий архив: 2005.10.16;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.035 c
1-1127316422
NikNet
2005-09-21 19:27
2005.10.16
А как в RxRichEdit Вставить рисунок например смайл?


1-1127800740
ShotGun
2005-09-27 09:59
2005.10.16
Как деархивировать zip file?


14-1127660413
alsov
2005-09-25 19:00
2005.10.16
Форма без заголовка, с возможностью ресайза


14-1127302393
palva
2005-09-21 15:33
2005.10.16
Что деется!


2-1127128160
Андрей гость
2005-09-19 15:09
2005.10.16
сложный запрос на выборку одинаковых записей