![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
CallBack [D5]
Eugene Zelikovsky © (2001-12-14 13:58:00)Народ пожалуйста объясните как работать с CallBack.
Общение Dll с прогой.
Если можно кусочек кода.
СПАСИБО!
Eugene Zelikovsky (2001-12-15 13:00:00) [1]Спасибо всем Заработала.!!!!!!!
> petr_v_a
Твой подход оказался наиболее рабочий.... с небольшими поправаками под мою прогу...
>iZEN
И тебе спасибо за справку... и экскурс в историю!!!!
y-soft (2001-12-15 10:29:00) [2]>Eugene Zelikovsky ©
Пояснения:
Библиотека совсем не обязана знать тип нашего объекта, поэтому просто передаем нетипированный указатель при вызове процедуры из библиотеки. Есть языки, в которых вообще отсутствуют ссылочные типы - в этом случае стоит приводить указатель на наш объект к Integer.
procedure TMyObject.CallSomeProc;
begin
SomeProc(Self, @MyCallback);
end;
В коде Dll:
procedure SomeProc(Reference : pointer; MyCbk : TMyCallback); stdcall;
begin
//...Какие-то действия
MyCbk(Reference); //Вызов Callback
end;
Соответственно в обработчике процедуры обратного вызова производим явно обратное приведение типов
procedure MyCallback(Reference : pointer); stdcall;
begin
TMyObject(Reference).SomeMethod; //вот здесь!!!
end;
В COM/DCOM, кстати, для аналогичных целей используются совершенно иные механизмы
iZEN (2001-12-15 01:37:00) [3]>TMyProcedure = procedure(a: Integer; b: Char; c: String[23]);
Поправочка:
type
TMyProcedure = procedure(a: Integer; b: Char; c: String[83]);
iZEN (2001-12-15 01:34:00) [4]Советую не связывать понятия callback и COM/DCOM, это несильно помогает в изучении проблемы.
iZEN (2001-12-15 01:30:00) [5]callback -- так называемый, "обратный вызов". Он придуман для того, чтобы любая программа могла "подсунуть" свою функцию(её адрес) другой программе, чтобы последняя(другая программа) могла вызвать её в первой без перекомпиляции и/или анализа кода первой программы -- это грубовато.
callback-и используются в любой оконной программе с обработкой событий: например, обработчики событий, которые пишет программист, являются непосредственными участниками callback-вызовов из главной функции обработчика событий окна Windows. Вот и всё.
Да, ещё, когда пишете обработчик события нажатия на кнопку в Delphi -- Вы пишете CallBack-процедуру, которую потом компилятор назначит функции окна кнопки.
Ещё в раннем Pascal-е для обеспечения механизма callback (обратного, или позднего вызова) служит процедурный тип:
type
TMyProcedure = procedure(a: Integer; b: Char; c: String[23]);
var
MyHandler: TMyProcedure;
procedure OtherProcedure(a: Integer; b: Char; c: String[83]);
begin
WriteLn(a);
WriteLn(b);
WriteLn(c);
end;
BEGIN
...
MyHandler := OtherProcedure;
...
MyHandler(10, "f", "Привет из глубины души!");
END.
Так что, лучше сначала изучите работу с DLL, это будет более логично.
petr_v_a (2001-12-15 00:39:00) [6]>Eugene Zelikovsky Почему один раз, это уж в логике программы смотри, тут кроме тебя вряли кто разберется, по крайней мере, это уже другой вопрос. Трудись,отлаживай дальше сам, и ни на кого не обращай внимания :)
Eugene Zelikovsky (2001-12-14 23:52:00) [7]>IZEN
в более не менее приличной книжке работа с DLL описанна типа:
вы можете засунуть ту да функцию которая будет вам считать 2+2...
и т.п.
А работа с callback восновном написанна в разделе COM/DCOM и в этом вся штука.... с которыми я только начинаю осваиваться...
Ну не когда не использовал я CALLBACKи .... вот теперь хочу научиться....
и нечего здесь возмущаться... Если умный подскажи... если нет молчи...
iZEN (2001-12-14 23:36:00) [8]Работа с DLL в любой более-менее приличной книжке по Delphi описывается.
Купил книжку, прочитал, понял(это обязательно!).
И чего здесь разговоры разводить и огороды городить?
P.S. Человек не знает как работать с DLL -- пусть учится, а потом уже думает, стоит ли туда сокеты запихивать.
Eugene Zelikovsky (2001-12-14 23:14:00) [9]>petr_v_a
Вообщем я заставил работать то метод который ты подсказал.... но только на один раз ... потом ему пофигу... не реагирует...
> y-soft
С твоим методом я не разобралсь
что ты имел в виду:
procedure MyCallback(Reference : pointer); stdcall;
begin
--- TMyObject(Reference).SomeMethod; ---//вот здесь
end;
petr_v_a (2001-12-14 21:49:00) [10]>y-soft
А вот "качестве функций обратного вызова метод" не просто "Можно и не использовать", а если "использовать", то "аксес волейшон" гарантирован
y-soft (2001-12-14 21:34:00) [11]>Eugene Zelikovsky ©
Можно и не использовать в качестве функций обратного вызова метод,а передавать в качестве параметров отдельно ссылку на вызывающий объект и адрес линейной функции-переходника. Еще лучше использовать для работы с Dll соглашение stdcall (добьемся лучшей совместимости с другими средствами разработки). Например, так (только общий подход):
type
TMyCallback = procedure(Reference : pointer);stdcall;//Callback-процедура-переходник
Экспортируемая процедура:
procedure SomeProc(Reference : pointer; MyCbk : TMyCallback); stdcall;
Вызывать ее так:
procedure TMyObject.CallSomeProc;
begin
SomeProc(Self, @MyCallback);
end;
procedure TMyObject.SomeMethod;
begin
//Какие-нибудь действия
end;
Обработчик процедуры обратного вызова:
procedure MyCallback(Reference : pointer); stdcall;
begin
TMyObject(Reference).SomeMethod;
end;
Может такой вариант больше понравится :)
petr_v_a (2001-12-14 20:35:00) [12]>Eugene Zelikovsky
а я предупреждал :) Я идеюподкинул, что тут все в кодеправильно, не отвечаю.
Anatoly Podgoretsky (2001-12-14 20:19:00) [13]Да аксес волейшон задолбали :-)
Eugene Zelikovsky (2001-12-14 20:01:00) [14]>petr_v_a
Все хорошо ... только аксес волейшон задолбали ...
Дурной вопрос
что ты имел в виду
function Cbak( info:pointer)
begin
showmessage("oops!");
end;
там где не дописанно... какая функция.... но это так глюк..
и как избугать этих самых аксесов ?
Я уже не знаю что и думать...
Прога загибается на моменте аналагичном этому в твоем коде...CbakAddr:=addr;
petr_v_a (2001-12-14 18:32:00) [15]Если я правильно понял, что тебе надо:
в exe
procedure MyCallBackregister( proc:pointer);external "mylib.dll";
function Cbak( info:pointer)
begin
showmessage("oops!");
end;
/* где-то при загрузке */
MyCallackRegister(@cbak);
в DLL
type
TMyCallBackProc=procedure( info:pointer);
var
CbakAddr:TMyCallBackProc;
..........
procedure MyCallackRegister( addr:TMyCallBackProc);// и не забудь ее экспортировать
begin
CbakAddr:=addr;
end;
......................
/* а это обработчик события */
procedure Datamodule1PosleAtomnoiVoiny( sender: TTerrorist);
begin
CbackAddr(sender);
end;
!!!писал прям тут, возможно где-нить че-нить не срастается, но идея от этого не страдает
Eugene Zelikovsky (2001-12-14 17:35:00) [16]Вот что я написал в DLL:
procedure ClientRead(servers: TServerSocket; EventHandler: TSocketNotifyEvent);export;
begin
ServerS.OnClientRead:= EventHandler;
end;
В Выз. коде:
Type
TForm1 = class(TForm)
Memo1: TMemo;
procedure OnClientRead(Sender: TObject; Socket: TCustomWinSocket);
procedure TForm1.OnClientRead(Sender: TObject; Socket: TCustomWinSocket);
begin
memo1.lines.Insert(0,Socket.ReceiveText);
end;
И еще что имелось в виду :
SetOnClientRead(ServerSocketInstanceCreatedInDll, MyObjectInstance.OnClientRead);
Digitman (2001-12-14 16:56:00) [17]Приводи СВОЙ, якобы неработающий, фрагмент кода - прокомментирую, где ты там чего делаешь конкретно. Ну как тебе объяснять, на пальцах ?
Digitman (2001-12-14 16:54:00) [18]что значит - "дергать" ? До каких пор на жаргоне дурацком изъясняться будем ????
TSocketServer, созданный тобой в DLL, в параметре Socket события OnClientRead извещает тебя о том, какой конкретно клиент передал тебе пакет данных.
Eugene Zelikovsky (2001-12-14 16:35:00) [19]OK:)
Но вот с Вызывающим кодом заминка... по подробней можно? То что у тебя написанно ... никак не воспринимает EventHendler .... признаюсь я даже не совсем понял что мы делаем в нем. .....
И еще а обязательно в Вызывающем коде дергать Socket... ?
Digitman (2001-12-14 16:27:00) [20]В КАКОЙ ПРОГРАММЕ ? И DLL и EXE - это программы . Пользуйся, по кр.мере, такими терминами как "вызывающий код" и "вызываемый код". Иначе - ни черта непонятно, о чем ты там....