读书人

哪位高手能给详细的讲解一下回调函数

发布时间: 2012-06-06 16:44:11 作者: rapoo

谁能给详细的讲解一下回调函数
百度了不少,看的还是有些晕,谢谢,具体如何声明,如何使用,什么情况下使用

[解决办法]
那你还是照着做一遍吧,我们再讲你还是不懂
[解决办法]
顾名思义就是回调用呗,把一个函数当参数来传递,一般多用于dll中
看书是不会懂的,只有多练习,才能理解

[解决办法]
windows程序的主窗口消息处理过程,就是一个回调函数额~~~
[解决办法]
http://topic.csdn.net/u/20080714/15/3049b6b3-a614-4f27-b66c-b5740e8a67a1.html
看这个,确实让人晕
[解决办法]
把函数当参数

一搬类似于触发事件中用到
[解决办法]
和一般的函数一样的嘛,只不过回调是别人调用你的,一般函数则是自己声明自己调用.
既然是别人调用你的函数,那声明自然是由别人声明好了的,因为别人的程序先于你而写,
别人声明,但是由你定义,所以你需要把你定义的函数作为指针传递给别人.别人通过指针在适当时候调用

故名回调函数.
[解决办法]
LZ这例子也稍显复杂了点,难怪你看晕了,呵呵。

从代码看,大致的操作流程应该是——
Button1->Button3->Button2,
对应的功能应该是——
打开端口并设置回调函数->写数据->关闭端口

1.打开端口
这里创建了一个TComPort对象,并初始化了各个属性的值,关键代码是My_cPort.OnRxChar := My_cPort_OBJ.My_cPortRxChar,你定义的回调函数CallbackExample实际上就是在TMy_cPort_OBJ.My_cPortRxChar中使用的(实际上,这个代码稍显复杂的地方就在这里,做了2次回调,先触发My_cPort.OnRxChar事件,而这个事件实际上又是触发了TMy_cPort_OBJ.My_cPortRxChar,而TMy_cPort_OBJ.My_cPortRxChar中才会触发FCallback,FCallback中存的就是你定义的CallbackExample的指针,是在SetCallback(@CallbackExample)中赋值的),不过,从你贴出来的代码中,我没找到TMy_cPort_OBJ创建的地方,因此,你这段代码跑起来应该是会报异常的

2.写数据
实际上就是调用My_cPort的WriteStr方法,而在WriteStr中应该会触发My_cPort的OnRxChar事件(由于你没贴TComPort的实现代码,这里仅仅是猜测),通过第1点的说明,这时就会调用CallbackExample了

3.关闭端口
已经没什么好写的了,呵呵
[解决办法]
首先,我想说,在了解回调函数时,不必关注消息、事件、DLL,回调函数只是语言中一种特殊的函数传参方式。简单地说就是,语言允许将『函数』当成『数据』一样看待传递给参数,而不是直接在参数上求值,这时,作为参数传入的函数就成为『回调函数』。
下面用一个小例子来说明,什么叫『当成数据一样看待传递参数』和『直接在参数上求值』

Delphi(Pascal) code
type  TDateFun = function (): TDateTime; //声明一种函数类型,本质上是一个函数指针,但在delphi中不再用C中指针式的晦涩表示function IncDate1(ADate: TDateTime): TDateTime;//形参是日期类型begin  Result:= ADate+1;end;function IncDate2(AGetDate: TDateFun): TDateTime;//形参是函数类型,它要求传入满足上面定义的任意一个函数begin  Result:= AGetDate+1;//只有到这个位置,传入的函数才被执行end;procedure CallIncDate();begin  IncDate1(Now);//Now是 一个函数,IncDate1的参数不是函数类型,Now在这里被立即执行返回出当前时间传入到函数内部,函数内部不再对ADate求值  IncDate2(Now);//Now函数并没有在参数位置上立即被执行,而是当成指针传入,直到ADate在内部被调用时才执行end;
[解决办法]
我也没理解, 但是照着格式写就是了, 能通过能实现就好
这是我用回调函数找其他程序窗口里的一个checkbox
Delphi(Pascal) code
function EnumWindowsProcCHKBox(hwnd: THandle; lParam: LPARAM): boolean; stdcall;var  classname: array[0..16] of char;  edith, HandlFromCaption : THandle;begin  GetClassName(hwnd,classname,16);  HandlFromCaption:= FindWindow(nil, 窗口标题);  if (classname = 'Txhtool')  and (hwnd = HandlFromCaption)  then  begin    edith:= findwindowex(hwnd,0,'TPageControl',nil);    edith:= findwindowex(edith,0,'TCheckBox','保存提示');    if SendMessage(edith, BM_GETCHECK, 1, 0) = 1 then    begin      bBeforeSaveChecked:= True;    end    else    begin      bBeforeSaveChecked:= False;    end;  end;  result:= true;end;
[解决办法]
就是函数指针。
[解决办法]
简单说就是定义一个方法,然后把这个方法指针告诉别人,让别人去执行这个方法。
[解决办法]
type TCallback = procedure(s: pchar); stdcall; //回调 定义一个函数指针类型
FCallback: TCallback; //回调 定义函数指针 与 i:integer;一样



procedure CallbackExample(s: pchar); stdcall;
//很正常地定义一个函数 只不过与TCallback的参数,返回值一模一样 我们可以认为 CallbackExample
是TCallback类型的一个函数指针
procedure CallbackExample(s: pchar); stdcall;//实例化函数指针,为函数指针赋值
// 就像i:=5;i:integer;
begin
Form1.Memo1.Text := Form1.Memo1.Text + ' ' + (s);
end;

一般地,我们调用函数是这个样子
procedure mytes();
begin
CallbackExample(PChar('回调测试'));//
end;

但是,回调函数就是把函数指针作为参数传结另一函数

procedure GetCallback(FCallback:TCallback;i:integer);
//看这里 就和 i 一样
var
ptest:PChar;
j:integer;
begin
ptest:=PChar("我要传的参数");
if Assigned(FCallback) then
FCallback(ptest);//看看这里 ptest 的内容 是由GetCallback函数内部 赋值的
//那么 ptest的值不同 FCallback执行的结果不同 这个例子不太好,
//假设 j:=FCallback(pTest); 那么,ptest的内容不同,j的结果就不同
我们可以这样
case j of
1:begin
结果不同,执行不同的操作
end;
2:begin
结果不同,执行不同的操作
end;
end;
我们需要知道的是 j的值 至于FCallback怎么实现的,对于 GetCallback来说,并不关心
end;



读书人网 >.NET

热点推荐