求救!CALLBACK函数是什么来的???

eyesonmecn 2003-03-19 09:14:45
void CALLBACK ReadTheard(unsigned char *buf)
{
char ReadData[24];
char TempData[24];
char rbuf[20];

//memcpy(rbuf,buf);
memcpy(rbuf, buf, 20);
if (buf[2]==0) {
for ( int i=3;i<24;i++) {
TempData[i-3]=char(buf[i]);
// strcpy(ReadData,buf);
//ShowMessage(TempData[4]);
}
strcpy(ReadData,TempData);
Form1->LabelReadData->Caption= ReadData; //char(buf[2]);
}else{
Form1->LabelReadData->Caption= char(buf[2]);
}
if (rbuf[3]==8) {
Form1->LabelReadData->Caption
=IntToStr(rbuf[10]/16*10+(rbuf[10]%16))+" "+
IntToStr(rbuf[9]/16*10+(rbuf[9]%16))+ " "+
IntToStr(rbuf[8]/16*10+(rbuf[8]%16))+" "+
IntToStr(rbuf[7]/16*10+(rbuf[7]%16))+" "+
IntToStr(rbuf[6]/16*10+(rbuf[6]%16))+" "+
IntToStr(rbuf[5]/16*10+(rbuf[5]%16))+" "+
IntToStr(rbuf[4]/16*10+(rbuf[4]%16));
}
int i=StrToInt(Form1->LabelCounter->Caption)+1;
// Form1->LabelCounter->Caption=IntToStr(i);
if (rbuf[3]==1) {
Form1->LabelCounter->Caption=IntToStr(i);
Form1->LabelReadData->Caption
=IntToStr(rbuf[7])+
IntToStr(rbuf[8])+
IntToStr(rbuf[9])+
IntToStr(rbuf[10])+
IntToStr(rbuf[11])+
IntToStr(rbuf[12])+
IntToStr(rbuf[13])+
IntToStr(rbuf[14]);
}

}
各位高人,请问CALLBACK函数有什么用的,它返回什么的,还有我对这段程序的存储操作不是好明,我想请各高人们一一解释程序的各部分,多谢,高分求教!!
...全文
45 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
nightfallrove 2003-05-19
  • 打赏
  • 举报
回复
回调函数运行结束后调用它的函数才返回的.
eyesonmecn 2003-03-22
  • 打赏
  • 举报
回复
哪么回调函数是运行调用它的函数之前运行,还是当调用它的函数运行完成后才调用呢?
zky 2003-03-21
  • 打赏
  • 举报
回复
__stdcall
chifengwatch 2003-03-19
  • 打赏
  • 举报
回复

发信人: lovexp (lovexp), 信区: VC
标 题: Re: 请问大侠!什么是回调函数,如何编写回调函数?
发信站: 浙江大学海纳百川站 (Wed Nov 13 13:17:16 2002)


首先 回调函数是函数 如何定义函数呢?我的理解是给予一定的输入,得到一定的输出,
这个输出可以是各种各样的状态和东西。那么什么是回调函数呢?回调函数就是你去调用
一个函数,但是这个函数约定要调用你的一个函数,你的这个函数就是回调函数,可能是
作为那个函数的一个输入给予的。举一个例子,比如你调用一个winapi,好了,他的确可
以得到你想要得到的东西,但是他并不想直接把结果给你再处理,或者他认为这样设计太
烂了,也可能是他认为他这个函数的目的应该是把所有的事情都做好了,那么他又不知道
你要如何处理这些结果,那么简单,你给他一个回调函数,他调用你的这个函数处理就行
了,当然这个函数可能是他已经约定的了。这可能是一个很浅的认识,其实这只是一种想
法并且有人去做了而已。看看有人的说法:

回调函数、消息和事件例程 xiaoran(原作)

调用(calling)机制从汇编时代起已经大量使用:准备一段现成的代码,调用者可以随
时跳转至此段代码的起始地址,执行完后再返回跳转时的后续地址。CPU为此准备了现成的
调用指令,调用时可以压栈保护现场,调用结束后从堆栈中弹出现场地址,以便自动返回
。借堆栈保护现场真是一项绝妙的发明,它使调用者和被调者可以互不相识,于是才有了
后来的函数和构件,使吾辈编程者如此轻松愉快。若评选对人类影响最大之发明,在火与
车轮之后,笔者当推压栈调用。
话虽这样说,此调用机制并非完美。回调函数就是一例。函数之类本是为调用者准备
的美餐,其烹制者应对食客了如指掌,但实情并非如此。例如,写一个快速排序函数供他
人调用,其中必包含比较大小。麻烦来了:此时并不知要比较的是何类数据--整数、浮点
数、字符串?于是只好为每类数据制作一个不同的排序函数。更通行的办法是在函数参数
中列一个回调函数地址,并通知调用者:君需自己准备一个比较函数,其中包含两个指针
类参数,函数要比较此二指针所指数据之大小,并由函数返回值说明比较结果。排序函数
借此调用者提供的函数来比较大小,借指针传递参数,可以全然不管所比较的数据类型。
被调用者回头调用调用者的函数(够咬嘴的),故称其为回调(callback)。
回调函数使程序结构乱了许多。Windows API 函数集中有不少回调函数,尽管有详尽
说明,仍使初学者一头雾水。恐怕这也是无奈之举。无论何种事物,能以树形结构单向描
述毕竟让人舒服些。如果某家族中孙辈又是某祖辈的祖辈,恐怕无人能理清其中的头绪。
但数据处理之复杂往往需要构成网状结构,非简单的客户/服务器关系能穷尽。
Windows 系统还包含着另一种更为广泛的回调机制,即消息机制。消息本是 Windows
的基本控制手段,乍看与函数调用无关,其实是一种变相的函数调用。发送消息的目的是
通知收方运行一段预先准备好的代码,相当于调用一个函数。消息所附带的 WParam 和 L
Param 相当于函数的参数,只不过比普通参数更通用一些。应用程序可以主动发送消息,
更多情况下是坐等 Windows 发送消息。一旦消息进入所属消息队列,便检感兴趣的那些,
跳转去执行相应的消息处理代码。操作系统本是为应用程序服务,由应用程序来调用。而
应用程序一旦启动,却要反过来等待操作系统的调用。这分明也是一种回调,或者说是一
种广义回调。其实,应用程序之间也可以形成这种回调。假如进程 B 收到进程 A 发来的
消息,启动了一段代码,其中又向进程 A 发送消息,这就形成了回调。这种回调比较隐蔽
,弄不好会搞成递归调用,若缺少终止条件,将会循环不已,直至把程序搞垮。若是故意
编写成此递归调用,并设好终止条件,倒是很有意思。但这种程序结构太隐蔽,除非十分
必要,还是不用为好。
利用消息也可以构成狭义回调。上面所举排序函数一例,可以把回调函数地址换成窗
口 handle。如此,当需要比较数据大小时,不是去调用回调函数,而是借 API 函数 Sen
dMessage 向指定窗口发送消息。收到消息方负责比较数据大小,把比较结果通过消息本身
的返回值传给消息发送方。所实现的功能与回调函数并无不同。当然,此例中改为消息纯
属画蛇添脚,反倒把程序搞得很慢。但其他情况下并非总是如此,特别是需要异步调用时
,发送消息是一种不错的选择。假如回调函数中包含文件处理之类的低速处理,调用方等
不得,需要把同步调用改为异步调用,去启动一个单独的线程,然后马上执行后续代码,
其余的事让线程慢慢去做。一个替代办法是借 API 函数 PostMessage 发送一个异步消息
,然后立即执行后续代码。这要比自己搞个线程省事许多,而且更安全。
如今我们是活在一个 object 时代。只要与编程有关,无论何事都离不开 object。但
object 并未消除回调,反而把它发扬光大,弄得到处都是,只不过大都以事件(event)
的身份出现,镶嵌在某个结构之中,显得更正统,更容易被人接受。应用程序要使用某个
构件,总要先弄清构件的属性、方法和事件,然后给构件属性赋值,在适当的时候调用适
当的构件方法,还要给事件编写处理例程,以备构件代码来调用。何谓事件?它不过是一
个指向事件例程的地址,与回调函数地址没什么区别。
不过,此种回调方式比传统回调函数要高明许多。首先,它把让人不太舒服的回调函
数变成一种自然而然的处理例程,使编程者顿觉气顺。再者,地址是一个危险的东西,用
好了可使程序加速,用不好处处是陷阱,程序随时都会崩溃。现代编程方式总是想法把地
址隐藏起来(隐藏比较彻底的如 VB 和 Java),其代价是降低了程序效率。事件例程使编
程者无需直接操作地址,但并不会使程序减速。更妙的是,此一改变,本是有损程序结构
之奇技怪巧变成一种崭新设计理念,不仅免去被人抨击,而且逼得吾等凡人净手更衣,细
细研读,仰慕至今。只是偶然静心思虑,发觉不过一瓶旧酒而已,故引得此番议论,让诸
君见笑了。

HUANG_JH 2003-03-19
  • 打赏
  • 举报
回复
memcpy(rbuf, buf, 20); //将buf的前20个内容复制给rbuf

if (buf[2]==0) { //如果buf[2]==0 则将buf[3]到buf[23]复制给Form1->LabelReadData->Caption
//如果buf[2]!=0 则Form1->LabelReadData->Caption= char(buf[2]);
for ( int i=3;i<24;i++) {
TempData[i-3]=char(buf[i]);
// strcpy(ReadData,buf);
//ShowMessage(TempData[4]);
}
strcpy(ReadData,TempData);
Form1->LabelReadData->Caption= ReadData; //char(buf[2]);
}else{
Form1->LabelReadData->Caption= char(buf[2]);
}
.....
下面的解释就应该可以理解了把?
HUANG_JH 2003-03-19
  • 打赏
  • 举报
回复
关于CALLBACK的含义请查阅Win32 SDK/API的精华篇

1,221

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧