- 浏览: 30562 次
- 来自: ...
最新评论
class CAsyncSocketExHelperWindow
{
public:
CAsyncSocketExHelperWindow()
{
//Initialize data
m_pAsyncSocketExWindowData = new t_AsyncSocketExWindowData[512]; //Reserve space for 512 active sockets
memset(m_pAsyncSocketExWindowData, 0, 512*sizeof(t_AsyncSocketExWindowData));
m_nWindowDataSize = 512;
m_nSocketCount = 0;
m_nWindowDataPos = 0;
//Create window
WNDCLASSEX wndclass;
wndclass.cbSize = sizeof wndclass;
wndclass.style = 0;
wndclass.lpfnWndProc = WindowProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = GetModuleHandle(0);
wndclass.hIcon = 0;
wndclass.hCursor = 0;
wndclass.hbrBackground = 0;
wndclass.lpszMenuName = 0;
wndclass.lpszClassName = _T("CAsyncSocketEx Helper Window");
wndclass.hIconSm = 0;
RegisterClassEx(&wndclass);
m_hWnd = CreateWindow(_T("CAsyncSocketEx Helper Window"), _T("CAsyncSocketEx Helper Window"), 0, 0, 0, 0, 0, 0, 0, 0, GetModuleHandle(0));
ASSERT( m_hWnd );
SetWindowLong(m_hWnd, GWL_USERDATA, (LONG)this);
};
virtual ~CAsyncSocketExHelperWindow()
{
//Clean up socket storage
delete[] m_pAsyncSocketExWindowData;
m_pAsyncSocketExWindowData = 0;
m_nWindowDataSize = 0;
m_nSocketCount = 0;
//Destroy window
if (m_hWnd)
{
DestroyWindow(m_hWnd);
m_hWnd = 0;
}
}
//Adds a socket to the list of attached sockets
BOOL AddSocket(CAsyncSocketEx *pSocket, int &nSocketIndex)
{
ASSERT( pSocket );
if (!m_nWindowDataSize)
{
ASSERT( !m_nSocketCount );
m_nWindowDataSize = 512;
m_pAsyncSocketExWindowData = new t_AsyncSocketExWindowData[512]; //Reserve space for 512 active sockets
memset(m_pAsyncSocketExWindowData, 0, 512 * sizeof(t_AsyncSocketExWindowData));
}
if (nSocketIndex != -1)
{
ASSERT( m_pAsyncSocketExWindowData );
ASSERT( m_nWindowDataSize>nSocketIndex );
ASSERT( m_pAsyncSocketExWindowData[nSocketIndex].m_pSocket == pSocket );
ASSERT( m_nSocketCount );
return TRUE;
}
//Increase socket storage if too small
if (m_nSocketCount >= m_nWindowDataSize - 10)
{
int nOldWindowDataSize = m_nWindowDataSize;
ASSERT( m_nWindowDataSize < MAX_SOCKETS );
m_nWindowDataSize += 512;
if (m_nWindowDataSize > MAX_SOCKETS)
m_nWindowDataSize = MAX_SOCKETS;
t_AsyncSocketExWindowData* tmp = m_pAsyncSocketExWindowData;
m_pAsyncSocketExWindowData = new t_AsyncSocketExWindowData[m_nWindowDataSize];
memcpy(m_pAsyncSocketExWindowData, tmp, nOldWindowDataSize * sizeof(t_AsyncSocketExWindowData));
memset(m_pAsyncSocketExWindowData + nOldWindowDataSize, 0, (m_nWindowDataSize - nOldWindowDataSize) * sizeof(t_AsyncSocketExWindowData));
delete[] tmp;
}
//Search for free slot
for (int i = m_nWindowDataPos; i < m_nWindowDataSize + m_nWindowDataPos; i++)
{
if (m_pAsyncSocketExWindowData[i % m_nWindowDataSize].m_pSocket == NULL)
{
m_pAsyncSocketExWindowData[i % m_nWindowDataSize].m_pSocket = pSocket;
nSocketIndex = i % m_nWindowDataSize;
m_nWindowDataPos = (i + 1) % m_nWindowDataSize;
m_nSocketCount++;
return TRUE;
}
}
//No slot found, maybe there are too much sockets!
return FALSE;
}
//Removes a socket from the socket storage
BOOL RemoveSocket(CAsyncSocketEx *pSocket, int &nSocketIndex)
{
UNREFERENCED_PARAMETER(pSocket);
ASSERT( pSocket );
if (nSocketIndex == -1)
return TRUE;
ASSERT( m_pAsyncSocketExWindowData );
ASSERT( m_nWindowDataSize > 0 );
ASSERT( m_nSocketCount > 0 );
ASSERT( m_pAsyncSocketExWindowData[nSocketIndex].m_pSocket == pSocket );
m_pAsyncSocketExWindowData[nSocketIndex].m_pSocket = 0;
nSocketIndex = -1;
m_nSocketCount--;
return TRUE;
}
//Processes event notifications sent by the sockets or the layers
static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
#if !NO_USE_CLIENT_TCP_CATCH_ALL_HANDLER
try
{
#endif//!NO_USE_CLIENT_TCP_CATCH_ALL_HANDLER
if (message >= WM_SOCKETEX_NOTIFY)
{
//Verify parameters
ASSERT( hWnd );
CAsyncSocketExHelperWindow *pWnd = (CAsyncSocketExHelperWindow *)GetWindowLong(hWnd, GWL_USERDATA);
ASSERT( pWnd );
if (message < (UINT)(WM_SOCKETEX_NOTIFY + pWnd->m_nWindowDataSize)) //Index is within socket storage
{
//Lookup socket and verify if it's valid
CAsyncSocketEx *pSocket = pWnd->m_pAsyncSocketExWindowData[message - WM_SOCKETEX_NOTIFY].m_pSocket;
SOCKET hSocket = wParam;
if (!pSocket)
return 0;
if (hSocket == INVALID_SOCKET)
return 0;
if (pSocket->m_SocketData.hSocket != hSocket)
return 0;
int nEvent = lParam & 0xFFFF;
int nErrorCode = lParam >> 16;
//Dispatch notification
#ifndef NOLAYERS
if (!pSocket->m_pFirstLayer)
{
#endif //NOLAYERS
//Dispatch to CAsyncSocketEx instance
switch (nEvent)
{
case FD_READ:
{
DWORD nBytes;
if (!pSocket->IOCtl(FIONREAD, &nBytes))
nErrorCode = WSAGetLastError();
if (nBytes != 0 || nErrorCode != 0)
pSocket->OnReceive(nErrorCode);
break;
}
case FD_FORCEREAD: //Forceread does not check if there's data waiting
pSocket->OnReceive(nErrorCode);
break;
case FD_WRITE:
pSocket->OnSend(nErrorCode);
break;
case FD_CONNECT:
pSocket->OnConnect(nErrorCode);
break;
case FD_ACCEPT:
pSocket->OnAccept(nErrorCode);
break;
case FD_CLOSE:
pSocket->OnClose(nErrorCode);
break;
}
}
#ifndef NOLAYERS
else //Dispatch notification to the lowest layer
{
if (nEvent == FD_READ)
{
DWORD nBytes;
if (!pSocket->IOCtl(FIONREAD, &nBytes))
nErrorCode = WSAGetLastError();
if (nBytes != 0 || nErrorCode != 0)
pSocket->m_pLastLayer->CallEvent(nEvent, nErrorCode);
}
else
pSocket->m_pLastLayer->CallEvent(nEvent, nErrorCode);
}
}
#endif //NOLAYERS
return 0;
}
#ifndef NOLAYERS
else if (message == WM_SOCKETEX_TRIGGER) //Notification event sent by a layer
{
//Verify parameters, lookup socket and notification message
if (!wParam)
return 0;
CAsyncSocketEx *pSocket = (CAsyncSocketEx *)wParam;
CAsyncSocketExLayer::t_LayerNotifyMsg *pMsg = (CAsyncSocketExLayer::t_LayerNotifyMsg *)lParam;
if (pSocket->m_SocketData.hSocket == INVALID_SOCKET) {
delete pMsg;
return 0;
}
int nEvent = pMsg->lEvent & 0xFFFF;
int nErrorCode = pMsg->lEvent >> 16;
//Dispatch to layer
if (pMsg->pLayer)
pMsg->pLayer->CallEvent(nEvent, nErrorCode);
else
{
//Dispatch to socket class
switch (nEvent)
{
case FD_READ:
if (pSocket->m_lEvent & FD_READ)
pSocket->OnReceive(nErrorCode);
break;
case FD_FORCEREAD:
if (pSocket->m_lEvent & FD_FORCEREAD)
pSocket->OnReceive(nErrorCode);
break;
case FD_WRITE:
if (pSocket->m_lEvent & FD_WRITE)
pSocket->OnSend(nErrorCode);
break;
case FD_CONNECT:
if (pSocket->m_lEvent & FD_CONNECT)
pSocket->OnConnect(nErrorCode);
break;
case FD_ACCEPT:
if (pSocket->m_lEvent & FD_ACCEPT)
pSocket->OnAccept(nErrorCode);
break;
case FD_CLOSE:
if (pSocket->m_lEvent & FD_CLOSE)
pSocket->OnClose(nErrorCode);
break;
}
}
delete pMsg;
return 0;
}
#endif //NOLAYERS
else if (message == WM_SOCKETEX_GETHOST)
{
//WSAAsyncGetHostByName reply
//Verify parameters
ASSERT( hWnd );
CAsyncSocketExHelperWindow *pWnd = (CAsyncSocketExHelperWindow *)GetWindowLong(hWnd, GWL_USERDATA);
ASSERT( pWnd );
CAsyncSocketEx *pSocket = NULL;
int i;
for (i = 0; i < pWnd->m_nWindowDataSize; i++)
{
pSocket = pWnd->m_pAsyncSocketExWindowData[i].m_pSocket;
if (pSocket && pSocket->m_hAsyncGetHostByNameHandle &&
pSocket->m_hAsyncGetHostByNameHandle == (HANDLE)wParam)
break;
}
if (i == pWnd->m_nWindowDataSize)
return 0;
int nErrorCode = lParam >> 16;
if (nErrorCode) {
pSocket->OnConnect(nErrorCode);
return 0;
}
SOCKADDR_IN sockAddr = {0};
sockAddr.sin_family = AF_INET;
sockAddr.sin_addr.s_addr = ((LPIN_ADDR)((LPHOSTENT)pSocket->m_pAsyncGetHostByNameBuffer)->h_addr)->s_addr;
sockAddr.sin_port = htons((u_short)pSocket->m_nAsyncGetHostByNamePort);
if (!pSocket->OnHostNameResolved(&sockAddr))
{
return 0;
}
BOOL res = pSocket->Connect((SOCKADDR*)&sockAddr, sizeof(sockAddr));
delete[] pSocket->m_pAsyncGetHostByNameBuffer;
pSocket->m_pAsyncGetHostByNameBuffer = 0;
pSocket->m_hAsyncGetHostByNameHandle = 0;
if (!res && GetLastError() != WSAEWOULDBLOCK)
pSocket->OnConnect(GetLastError());
return 0;
}
return DefWindowProc(hWnd, message, wParam, lParam);
#if !NO_USE_CLIENT_TCP_CATCH_ALL_HANDLER
}
catch(CException* e){
TCHAR szError[1024];
e->GetErrorMessage(szError, ARRSIZE(szError));
const CRuntimeClass* pRuntimeClass = e->GetRuntimeClass();
LPCSTR pszClassName = (pRuntimeClass) ? pRuntimeClass->m_lpszClassName : NULL;
if (!pszClassName)
pszClassName = "CException";
TRACE(_T("*** Unknown %hs exception in CAsyncSocketExHelperWindow::WindowProc - %s\n"), pszClassName, szError);
e->Delete();
}
catch (...) {
// TODO: This exception handler should definitively *not* be here. Though we seem to need it to
// catch some very strange crashs which deal with socket deletion problems in the client's TCP socket.
TRACE("*** Unknown exception in CAsyncSocketExHelperWindow::WindowProc\n");
ASSERT(0);
}
return 0;
#endif//!NO_USE_CLIENT_TCP_CATCH_ALL_HANDLER
}
{
public:
CAsyncSocketExHelperWindow()
{
//Initialize data
m_pAsyncSocketExWindowData = new t_AsyncSocketExWindowData[512]; //Reserve space for 512 active sockets
memset(m_pAsyncSocketExWindowData, 0, 512*sizeof(t_AsyncSocketExWindowData));
m_nWindowDataSize = 512;
m_nSocketCount = 0;
m_nWindowDataPos = 0;
//Create window
WNDCLASSEX wndclass;
wndclass.cbSize = sizeof wndclass;
wndclass.style = 0;
wndclass.lpfnWndProc = WindowProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = GetModuleHandle(0);
wndclass.hIcon = 0;
wndclass.hCursor = 0;
wndclass.hbrBackground = 0;
wndclass.lpszMenuName = 0;
wndclass.lpszClassName = _T("CAsyncSocketEx Helper Window");
wndclass.hIconSm = 0;
RegisterClassEx(&wndclass);
m_hWnd = CreateWindow(_T("CAsyncSocketEx Helper Window"), _T("CAsyncSocketEx Helper Window"), 0, 0, 0, 0, 0, 0, 0, 0, GetModuleHandle(0));
ASSERT( m_hWnd );
SetWindowLong(m_hWnd, GWL_USERDATA, (LONG)this);
};
virtual ~CAsyncSocketExHelperWindow()
{
//Clean up socket storage
delete[] m_pAsyncSocketExWindowData;
m_pAsyncSocketExWindowData = 0;
m_nWindowDataSize = 0;
m_nSocketCount = 0;
//Destroy window
if (m_hWnd)
{
DestroyWindow(m_hWnd);
m_hWnd = 0;
}
}
//Adds a socket to the list of attached sockets
BOOL AddSocket(CAsyncSocketEx *pSocket, int &nSocketIndex)
{
ASSERT( pSocket );
if (!m_nWindowDataSize)
{
ASSERT( !m_nSocketCount );
m_nWindowDataSize = 512;
m_pAsyncSocketExWindowData = new t_AsyncSocketExWindowData[512]; //Reserve space for 512 active sockets
memset(m_pAsyncSocketExWindowData, 0, 512 * sizeof(t_AsyncSocketExWindowData));
}
if (nSocketIndex != -1)
{
ASSERT( m_pAsyncSocketExWindowData );
ASSERT( m_nWindowDataSize>nSocketIndex );
ASSERT( m_pAsyncSocketExWindowData[nSocketIndex].m_pSocket == pSocket );
ASSERT( m_nSocketCount );
return TRUE;
}
//Increase socket storage if too small
if (m_nSocketCount >= m_nWindowDataSize - 10)
{
int nOldWindowDataSize = m_nWindowDataSize;
ASSERT( m_nWindowDataSize < MAX_SOCKETS );
m_nWindowDataSize += 512;
if (m_nWindowDataSize > MAX_SOCKETS)
m_nWindowDataSize = MAX_SOCKETS;
t_AsyncSocketExWindowData* tmp = m_pAsyncSocketExWindowData;
m_pAsyncSocketExWindowData = new t_AsyncSocketExWindowData[m_nWindowDataSize];
memcpy(m_pAsyncSocketExWindowData, tmp, nOldWindowDataSize * sizeof(t_AsyncSocketExWindowData));
memset(m_pAsyncSocketExWindowData + nOldWindowDataSize, 0, (m_nWindowDataSize - nOldWindowDataSize) * sizeof(t_AsyncSocketExWindowData));
delete[] tmp;
}
//Search for free slot
for (int i = m_nWindowDataPos; i < m_nWindowDataSize + m_nWindowDataPos; i++)
{
if (m_pAsyncSocketExWindowData[i % m_nWindowDataSize].m_pSocket == NULL)
{
m_pAsyncSocketExWindowData[i % m_nWindowDataSize].m_pSocket = pSocket;
nSocketIndex = i % m_nWindowDataSize;
m_nWindowDataPos = (i + 1) % m_nWindowDataSize;
m_nSocketCount++;
return TRUE;
}
}
//No slot found, maybe there are too much sockets!
return FALSE;
}
//Removes a socket from the socket storage
BOOL RemoveSocket(CAsyncSocketEx *pSocket, int &nSocketIndex)
{
UNREFERENCED_PARAMETER(pSocket);
ASSERT( pSocket );
if (nSocketIndex == -1)
return TRUE;
ASSERT( m_pAsyncSocketExWindowData );
ASSERT( m_nWindowDataSize > 0 );
ASSERT( m_nSocketCount > 0 );
ASSERT( m_pAsyncSocketExWindowData[nSocketIndex].m_pSocket == pSocket );
m_pAsyncSocketExWindowData[nSocketIndex].m_pSocket = 0;
nSocketIndex = -1;
m_nSocketCount--;
return TRUE;
}
//Processes event notifications sent by the sockets or the layers
static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
#if !NO_USE_CLIENT_TCP_CATCH_ALL_HANDLER
try
{
#endif//!NO_USE_CLIENT_TCP_CATCH_ALL_HANDLER
if (message >= WM_SOCKETEX_NOTIFY)
{
//Verify parameters
ASSERT( hWnd );
CAsyncSocketExHelperWindow *pWnd = (CAsyncSocketExHelperWindow *)GetWindowLong(hWnd, GWL_USERDATA);
ASSERT( pWnd );
if (message < (UINT)(WM_SOCKETEX_NOTIFY + pWnd->m_nWindowDataSize)) //Index is within socket storage
{
//Lookup socket and verify if it's valid
CAsyncSocketEx *pSocket = pWnd->m_pAsyncSocketExWindowData[message - WM_SOCKETEX_NOTIFY].m_pSocket;
SOCKET hSocket = wParam;
if (!pSocket)
return 0;
if (hSocket == INVALID_SOCKET)
return 0;
if (pSocket->m_SocketData.hSocket != hSocket)
return 0;
int nEvent = lParam & 0xFFFF;
int nErrorCode = lParam >> 16;
//Dispatch notification
#ifndef NOLAYERS
if (!pSocket->m_pFirstLayer)
{
#endif //NOLAYERS
//Dispatch to CAsyncSocketEx instance
switch (nEvent)
{
case FD_READ:
{
DWORD nBytes;
if (!pSocket->IOCtl(FIONREAD, &nBytes))
nErrorCode = WSAGetLastError();
if (nBytes != 0 || nErrorCode != 0)
pSocket->OnReceive(nErrorCode);
break;
}
case FD_FORCEREAD: //Forceread does not check if there's data waiting
pSocket->OnReceive(nErrorCode);
break;
case FD_WRITE:
pSocket->OnSend(nErrorCode);
break;
case FD_CONNECT:
pSocket->OnConnect(nErrorCode);
break;
case FD_ACCEPT:
pSocket->OnAccept(nErrorCode);
break;
case FD_CLOSE:
pSocket->OnClose(nErrorCode);
break;
}
}
#ifndef NOLAYERS
else //Dispatch notification to the lowest layer
{
if (nEvent == FD_READ)
{
DWORD nBytes;
if (!pSocket->IOCtl(FIONREAD, &nBytes))
nErrorCode = WSAGetLastError();
if (nBytes != 0 || nErrorCode != 0)
pSocket->m_pLastLayer->CallEvent(nEvent, nErrorCode);
}
else
pSocket->m_pLastLayer->CallEvent(nEvent, nErrorCode);
}
}
#endif //NOLAYERS
return 0;
}
#ifndef NOLAYERS
else if (message == WM_SOCKETEX_TRIGGER) //Notification event sent by a layer
{
//Verify parameters, lookup socket and notification message
if (!wParam)
return 0;
CAsyncSocketEx *pSocket = (CAsyncSocketEx *)wParam;
CAsyncSocketExLayer::t_LayerNotifyMsg *pMsg = (CAsyncSocketExLayer::t_LayerNotifyMsg *)lParam;
if (pSocket->m_SocketData.hSocket == INVALID_SOCKET) {
delete pMsg;
return 0;
}
int nEvent = pMsg->lEvent & 0xFFFF;
int nErrorCode = pMsg->lEvent >> 16;
//Dispatch to layer
if (pMsg->pLayer)
pMsg->pLayer->CallEvent(nEvent, nErrorCode);
else
{
//Dispatch to socket class
switch (nEvent)
{
case FD_READ:
if (pSocket->m_lEvent & FD_READ)
pSocket->OnReceive(nErrorCode);
break;
case FD_FORCEREAD:
if (pSocket->m_lEvent & FD_FORCEREAD)
pSocket->OnReceive(nErrorCode);
break;
case FD_WRITE:
if (pSocket->m_lEvent & FD_WRITE)
pSocket->OnSend(nErrorCode);
break;
case FD_CONNECT:
if (pSocket->m_lEvent & FD_CONNECT)
pSocket->OnConnect(nErrorCode);
break;
case FD_ACCEPT:
if (pSocket->m_lEvent & FD_ACCEPT)
pSocket->OnAccept(nErrorCode);
break;
case FD_CLOSE:
if (pSocket->m_lEvent & FD_CLOSE)
pSocket->OnClose(nErrorCode);
break;
}
}
delete pMsg;
return 0;
}
#endif //NOLAYERS
else if (message == WM_SOCKETEX_GETHOST)
{
//WSAAsyncGetHostByName reply
//Verify parameters
ASSERT( hWnd );
CAsyncSocketExHelperWindow *pWnd = (CAsyncSocketExHelperWindow *)GetWindowLong(hWnd, GWL_USERDATA);
ASSERT( pWnd );
CAsyncSocketEx *pSocket = NULL;
int i;
for (i = 0; i < pWnd->m_nWindowDataSize; i++)
{
pSocket = pWnd->m_pAsyncSocketExWindowData[i].m_pSocket;
if (pSocket && pSocket->m_hAsyncGetHostByNameHandle &&
pSocket->m_hAsyncGetHostByNameHandle == (HANDLE)wParam)
break;
}
if (i == pWnd->m_nWindowDataSize)
return 0;
int nErrorCode = lParam >> 16;
if (nErrorCode) {
pSocket->OnConnect(nErrorCode);
return 0;
}
SOCKADDR_IN sockAddr = {0};
sockAddr.sin_family = AF_INET;
sockAddr.sin_addr.s_addr = ((LPIN_ADDR)((LPHOSTENT)pSocket->m_pAsyncGetHostByNameBuffer)->h_addr)->s_addr;
sockAddr.sin_port = htons((u_short)pSocket->m_nAsyncGetHostByNamePort);
if (!pSocket->OnHostNameResolved(&sockAddr))
{
return 0;
}
BOOL res = pSocket->Connect((SOCKADDR*)&sockAddr, sizeof(sockAddr));
delete[] pSocket->m_pAsyncGetHostByNameBuffer;
pSocket->m_pAsyncGetHostByNameBuffer = 0;
pSocket->m_hAsyncGetHostByNameHandle = 0;
if (!res && GetLastError() != WSAEWOULDBLOCK)
pSocket->OnConnect(GetLastError());
return 0;
}
return DefWindowProc(hWnd, message, wParam, lParam);
#if !NO_USE_CLIENT_TCP_CATCH_ALL_HANDLER
}
catch(CException* e){
TCHAR szError[1024];
e->GetErrorMessage(szError, ARRSIZE(szError));
const CRuntimeClass* pRuntimeClass = e->GetRuntimeClass();
LPCSTR pszClassName = (pRuntimeClass) ? pRuntimeClass->m_lpszClassName : NULL;
if (!pszClassName)
pszClassName = "CException";
TRACE(_T("*** Unknown %hs exception in CAsyncSocketExHelperWindow::WindowProc - %s\n"), pszClassName, szError);
e->Delete();
}
catch (...) {
// TODO: This exception handler should definitively *not* be here. Though we seem to need it to
// catch some very strange crashs which deal with socket deletion problems in the client's TCP socket.
TRACE("*** Unknown exception in CAsyncSocketExHelperWindow::WindowProc\n");
ASSERT(0);
}
return 0;
#endif//!NO_USE_CLIENT_TCP_CATCH_ALL_HANDLER
}
相关推荐
在“经典回调函数实例”中,我们可以想象一个朋友打电话的情景来理解回调函数的工作原理。假设你有一个朋友A,他想要告诉你一些消息,但他只能在电话接通后才能告诉你。因此,A不会立即告诉你消息,而是先打给你,当...
通过这种方式,Delphi的回调函数实例可以在BPL中被调用,提供了一种灵活的方式来扩展和定制代码的行为。这种设计模式在各种场景下都非常有用,例如在多线程编程中更新UI、在图形库中处理用户交互,或者在数据库操作...
在C语言中一般用typedef来为回调函数定义别名(参数名)。 别名通过宏定义typedef来实现,不是简单的宏替换。可以用作同时声明指针型的多个对象。 比如: 代码如下:char *pa,pb;//pa是一个char型指针,但pb是一个...
在编程领域,回调函数是一种设计模式,它允许我们定义一个函数,这个函数可以在另一个函数执行完毕后被调用。在Android开发中,回调函数扮演着至关重要的角色,尤其是在处理异步操作、事件监听以及用户交互时。本...
回调函数在计算机编程中是一种设计模式,它允许我们定义一个函数,这个函数可以在其他函数执行完成之后被调用。在Java中,回调函数通常通过接口实现,即将接口作为参数传递给另一个方法,当该方法执行完毕后,会通过...
回调函数回调函数讲解及应用实例回调函数讲解及应用实例回调函数讲解及应用实例回调函数讲解及应用实例回调函数讲解及应用实例回调函数讲解及应用实例回调函数讲解及应用实例回调函数讲解及应用实例回调函数讲解及...
3. **创建回调函数实例**:在你的代码中定义一个该类型的函数指针,并将其指向你的回调函数。 ```cpp MyCallbackType myCallback = MyCallback; ``` 4. **传递回调函数**:将这个函数指针作为参数传递给其他函数...
以下是一个简单的回调函数实例: ```c #include #include int Test1(){ int i; for (i=0; i; i++){ printf("The %d th charactor is ", i); } return 0; } int main(){ void (*ptr)(); ptr = Test1; ptr...
在Delphi编程中,回调函数是一种非常重要的设计模式,它允许你传递一个方法或函数作为参数,以便在特定时刻由另一个函数或过程调用。回调函数可以极大地增加代码的灵活性和可扩展性,特别是在处理异步操作或者需要...
回调函数的基本用法 1、定义回调函数:首先定义一个符合预期签名的函数。例如,一个简单的回调函数可以是这样的 2、定义接受回调函数的函数:这个函数接受一个函数指针作为参数,并在某个时刻调用它。 3、调用函数并...
例如,下面是一个简单的JavaScript回调函数实例: ```javascript function doSomethingAsync(callback) { setTimeout(() => { // 假设这是一个异步操作 const result = '异步操作的结果'; callback(result); }...
首先,回调函数的基本结构是定义一个函数指针类型,然后将这个函数类型的实例作为参数传递给其他函数。例如: ```cpp typedef void (*CallbackType)(int); // 定义一个接受整型参数,无返回值的函数指针类型 void ...
回调函数则是编程中一种常见的设计模式,它允许函数将控制权返回给调用者,使得调用者可以在适当的时候执行特定的处理逻辑。在VC++中,将回调函数实现在DLL中,可以提供更加灵活的跨模块通信方式。 首先,我们需要...
在本实例中,我们将深入探讨如何在VC++中实现和使用回调函数。 首先,我们要理解回调函数的基本概念。在C++中,由于语言的特性,不能直接像某些动态类型语言那样传递函数作为参数。但是,通过函数指针或函数对象,...
Java回调函数实例代码详解 Java回调函数是一种编程模式,允许程序员在程序中定义一个函数,并将其传递给另一个程序,以便在需要时被调用。这种编程模式广泛应用于Java中,特别是在事件驱动编程、异步编程和多线程...
在编程领域,回调函数是一种非常重要的设计模式,它允许我们将一个方法作为参数传递给另一个方法,在特定条件下由被调用的方法执行。在C#中,回调函数同样被广泛使用,尤其是在异步编程、事件处理和自定义算法中。本...
在安卓应用开发中,回调函数是一种常见的编程设计模式,它允许一个对象在完成特定操作时通知另一个对象。这种模式在事件驱动的系统中尤为常见,比如用户点击按钮、网络请求完成或者数据加载完毕等场景。回调函数使得...
这个指针可以在回调函数中用来获取调用该函数的对象实例。例如,你可以使用`AfxSetUserWindowProc`或`AfxSetWndProc`来设置窗口过程,其中第二个参数就是回调函数。 4. **处理回调**: 当回调函数被调用时,它将...
ajax回调函数是怎么写的ajax回调函数是怎么写的ajax回调函数是怎么写的
回调函数在编程中是一种常见的设计模式,特别是在异步编程中,它被广泛应用于JavaScript、Python、C++等语言。回调函数的基本概念是将一个函数作为参数传递给另一个函数,然后在内部函数执行完毕后调用这个传入的...