Форум: "Основная";
Текущий архив: 2005.10.16;
Скачать: [xml.tar.bz2];
ВнизПередача и вызов процедуры/функции. Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.037 c