Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
1-1127820657
ZeroDivide
2005-09-27 15:30
2005.10.16
О самоуничтожении объекта.


2-1126707473
Anton22
2005-09-14 18:17
2005.10.16
StatusBar


1-1127809485
BaxTMaH
2005-09-27 12:24
2005.10.16
Как в Edit вводить только цифры?


14-1127220284
Дядя Фёдор
2005-09-20 16:44
2005.10.16
Как сделать чтоб при надатии кнопки содержимое Edit сохранялась в


3-1125469474
Nickolay
2005-08-31 10:24
2005.10.16
Запись/чтение массива в/из поле базы данных xml





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