CALLBACK 是什么意思

zyb_debug 2008-04-26 03:04:12
callback 回调函数到底是怎么回事
概念是什么
中间机理又是什么
...全文
445 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
就是一个概念的东西
你提供一个接口让别人调用你,对你而言就是回调,
对调用你的接口的人而言,就是一个普通的函数调用.

这里的接口可以是函数仿函数.
michney 2008-04-26
  • 打赏
  • 举报
回复
回调函数是由操作系统来在某一个合适的时间调用
合适时机是指:网络报文,用户输入,其他的一些事件...
zyb_debug 2008-04-26
  • 打赏
  • 举报
回复
比如说,这个程序
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
HRESULT hr;

// Create the DirectInput object.
hr = DirectInput8Create(hInstance, DIRECTINPUT_VERSION,
IID_IDirectInput8, (void**)&g_lpDI, NULL);

if FAILED(hr) return FALSE;

// grab the input devices attached
hr = g_lpDI->EnumDevices( DI8DEVCLASS_ALL, EnumDevicesCallback,
NULL, DIEDFL_ATTACHEDONLY );
if FAILED (hr) return FALSE;

// create a temporary string
string tempString;

// Loop through the vector of device names and put them in tempstring
tempString = "List of Installed Devices\n";
for (unsigned int i=0; i<DeviceList.size(); i++)
{
tempString += DeviceList[i];
tempString += "\n";
}

// throw up a message box just to display the names of the devices
MessageBox(NULL, tempString.c_str(), "Devices", MB_OK);

if (g_lpDI)
{
if (g_lpDIDevice)
{
// Always unacquire device before calling Release().
g_lpDIDevice->Unacquire();
g_lpDIDevice->Release();
g_lpDIDevice = NULL;
}
g_lpDI->Release();
g_lpDI = NULL;
}

return 0;
}

BOOL CALLBACK EnumDevicesCallback( const DIDEVICEINSTANCE* pdidInstance,
VOID* pContext )
{
HRESULT hr;

hr = g_lpDI->CreateDevice( pdidInstance->guidInstance, &g_lpDIDevice, NULL );

if( FAILED(hr) )
return DIENUM_STOP;
else
{
// add the current device to the vector
DeviceList.push_back(pdidInstance->tszInstanceName);
}
return DIENUM_CONTINUE;
}


EnumDevices 调用 EnumDevicesCallback 一直调用?直到把所有设备枚举完为止
zyb_debug 2008-04-26
  • 打赏
  • 举报
回复
还是不懂。
CALLBACK是两个函数一直调用么?
直到失败 或者结束为止??
Mobidogs 2008-04-26
  • 打赏
  • 举报
回复
在C/C++中,如果你把函数F1的指针(地址)作为参数传递给另一个函数F2,
当这个指针被用来调用它所指向的函数F1时,这就是回调函数(CALLBACK)。

typedef int (*F)(int,int);
int F1( int i,int j)
{
return (i + j);
}

int F2(int i,int j,F p)
{
return p(i,j);
}

void main()
{
F p = F1;
printf("%d",F2(100,200, p));
}

Xuon 2008-04-26
  • 打赏
  • 举报
回复
好的,知道了。
fhb13 2008-04-26
  • 打赏
  • 举报
回复
callback
定义如下:

#define CALLBACK __stdcall

而__stdcall表示的是一种函数调用约定,另外还有很多调用约定,如cdecl、pascal等。

简单举下stdcall和pascal的调用约定中的参数压栈顺序的区别。
如有下面一段代码:

MessageBox(Val1, Val2, Val3, Val4);

如果是stdcall调用,上面这个函数调用将会被编译成如下样子。

push Val4
push Val3
push Val2
push Val1
call MessageBox

如果是pascal调用,上面这个函数调用将会被编译成如下样子。

push Val1
push Val2
push Val3
push Val4
call MessageBox

而且函数调用约定还规定堆栈恢复由谁来做。
如果是stdcall是由被调用者来恢复,除了wsprintf这个函数。
如上面这个函数,被调者的返回指令将会是下面这个样子

ret 32

如果是cdecl是由调用者来恢复。
如上面这个函数,调用者的代码接在call指令之下还需要加入恢复堆栈的语句,如下:

push Val4
push Val3
push Val2
push Val1
call MessageBox
sub sp,32
zyb_debug 2008-04-26
  • 打赏
  • 举报
回复
int d3d::EnterMsgLoop( bool (*ptr_display)(float timeDelta) )
{
MSG msg;
::ZeroMemory(&msg, sizeof(MSG));

static float lastTime = (float)timeGetTime();

while(msg.message != WM_QUIT)
{
if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
else
{
float currTime = (float)timeGetTime();
float timeDelta = (currTime - lastTime)*0.001f;

ptr_display(timeDelta);

lastTime = currTime;
}
}
return msg.wParam;
}
函数是这个样子的
zyb_debug 2008-04-26
  • 打赏
  • 举报
回复
楼上的 那个叫做函数指针 并非CALLBACK
int d3d::EnterMsgLoop( bool (*ptr_display)(float timeDelta) )
{
MSG msg;
::ZeroMemory(&msg, sizeof(MSG));

while(msg.message != WM_QUIT)
{
if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
else
{
ptr_display(timeDelta);
lastTime = currTime;
}
}
return msg.wParam;
}

你说的应该是这个意思吧 只要在 ptr_display 里面写上一大堆东西就可以
并非 CALLBACK
MagiSu 2008-04-26
  • 打赏
  • 举报
回复
很简单,你给函数A传递一个指向函数B的指针,然后由A来调用B
zyb_debug 2008-04-26
  • 打赏
  • 举报
回复
B* pthis = reinterpret_cast <B*>(user_value); 这句什么意思

aa.registerCallback(B::foo, (unsigned long)&bb); B中有 foo?
iu_81 2008-04-26
  • 打赏
  • 举报
回复

typedef void (CALLBACK *FOO)(int other_value, unsigned long user_value); //定义函数指针类型,实际上制定了回调函数的接口

class A
{
public:
A(){};
void registerCallback(FOO foo, unsigned long user_value) //注册回调函数的方法
{
m_foo = foo;
m_user_value = user_value;
}

void test()
{
m_foo(0, m_user_value); //通过函数指针使用回调
}

private:
FOO m_foo; //回调函数指针
unsigned long m_user_value;
};

class B
{
public:
B(){}

static void CALLBACK foo(int other_value, unsigned long user_value) //用户程序实现回调接口
{
B* pthis = reinterpret_cast<B*>(user_value);
if(pthis)
{
pthis->test = 123;
}
}
private:
int test;
};

void main()
{
A aa;
B bb;
aa.registerCallback(B::foo, (unsigned long)&bb);
aa.test();
}

简单的说,回调函数就是A要用到B的模块,但B又要反过来调用A的函数,A的这个函数就叫回调函数。回调函数和普通的函数在本质上没有区别,不是前面所说的一定是系统来调用。
回调函数一般用在SDK的编写中,比如你要向其它用户提供一套下层开发包,你很可能需要和用户的程序进行交互,这时就会经常使用回调。
fallening 2008-04-26
  • 打赏
  • 举报
回复
不是()重载?
  • 打赏
  • 举报
回复
#define CALLBACK __stdcall

就是你提供一个函数,然后别人去调用你这个函数.
wqzq2020 2008-04-26
  • 打赏
  • 举报
回复
学习。。。。。

64,646

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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