一个函数在此处声明并使用(一般是低层,比如DLL),在其它地方实现(一般是上层,应用程序),这种函数就是回调函数。与回调函数相反的是正调函数(一般不这么叫),也就是一般OS低层提供给上层的API函数,让上层什么时候想使用这个函数,就直接调用这个函数。
回调函数是自动被调用的,用户不会直接调用它,但用户会填加其中的代码具体实现。正调函数,用户会主动地调用(或使用)的。
在动态库中声明函数原型:
- HV_API HRESULT__cdecl SetHvCallBack( HV_HANDLE hHandle, void *pFunction, void *pFirstParameter, WORD wVideoID, WORD wStream )
- typedef int (__cdecl *PLATE_NO_CALLBACK )( void *pFirstParameter, DWORD32 dwCarID, PSTR pcPlateNo, DWORD64 dwTimeMs)
应用程序声明函数原型:
- typedef HRESULT (_cdecl *tSetHvCallBack)(HV_HANDLE, void *, void *, WORD, WORD);
- typedef int ( *PLATE_NO_CALLBACK )( void *pFirstParameter, DWORD32 dwCarID, PSTR pcPlateNo, DWORD64 dw64TimeMs );
举例说明二者的调用机制:
回调函数的调用:
首先要在应用程序中声明并实现回调函数:
static int PlateNoCallBack(void *pFirstParameter, DWORD32 dwCarID, PSTR pcPlateNo, DWORD64 dw64TimeMs);//声明
int CWJSWDLLApp::PlateNoCallBack(void *pFirstParameter, DWORD32 dwCarID, PSTR pcPlateNo, DWORD64 dw64TimeMs)//实现
{
//读取车牌号
{
//读取车牌号
............ //函数体
return 0;
}
}
然后在应用程序中调用回调函数:是通过函数指针的方式调用的
wSetHvCallBack(IdentInfo[i].HvHandle, CWJSWDLLApp::PlateNoCallBack, &IdentInfo[i], 0, _TYPE_PLATE_STR)//调用
函数指针的调用
首先在应用程序中声明函数指针类型:
typedef HRESULT (_cdecl *tSetHvCallBack)(HV_HANDLE, void *, void *, WORD, WORD);
然后在应用程序中声明一个函数变量:
tSetHvCallBack wSetHvCallBack;
其次获取函数变量的地址:
wSetHvCallBack = (tSetHvCallBack)GetProcAddress(m_DllHandle, "SetHvCallBack");//
最后使用此函数变量:
wSetHvCallBack(IdentInfo[i].HvHandle, CWJSWDLLApp::PlateNoCallBack, &IdentInfo[i], 0, _TYPE_PLATE_STR)//使用