一个关于 overlapped I/O api 的疑问

2018-10-29 15:20:07 +08:00
 v2byy

在使 win32 overlapped I/O API 的过程中,关于 WSARecv 函数的 msdn 声明如下:

int WSAAPI WSARecv(
  SOCKET                             s,
  LPWSABUF                           lpBuffers,
  DWORD                              dwBufferCount,
  LPDWORD                            lpNumberOfBytesRecvd,
  LPDWORD                            lpFlags,
  LPWSAOVERLAPPED                    lpOverlapped,
  LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);

msdn 上关于这个 API 的解释如下:

The lpOverlapped parameter must be valid for the duration of the overlapped operation. If multiple I/O operations are simultaneously outstanding, each must reference a separate WSAOVERLAPPED structure.

If the lpCompletionRoutine parameter is NULL, the hEvent parameter of lpOverlapped is signaled when the overlapped operation completes if it contains a valid event object handle. An application can use WSAWaitForMultipleEvents or WSAGetOverlappedResult to wait or poll on the event object.

If lpCompletionRoutine is not NULL, the hEvent parameter is ignored and can be used by the application to pass context information to the completion routine. A caller that passes a non-NULL lpCompletionRoutine and later calls WSAGetOverlappedResult for the same overlapped I/O request may not set the fWait parameter for that invocation of WSAGetOverlappedResult to TRUE. In this case the usage of the hEvent parameter is undefined, and attempting to wait on the hEvent parameter would produce unpredictable results.

The completion routine follows the same rules as stipulated for Windows file I/O completion routines. The completion routine will not be invoked until the thread is in an alertable wait state such as can occur when the function WSAWaitForMultipleEvents with the fAlertable parameter set to TRUE is invoked.

按照文档的意思:如果 completionRoutine 不是 null 的话,可以使用 hEvent 参数在回调函数中来传递上下文信息。

那么假如我想传递一个 obj 给 completionRoutine 对应的回调函数,应该怎么传递呢? 试过以下的方式:

m_overlap.hEvent = new context_obj;

completionCallback((DWORD dwError,
	DWORD cbTransferred,
	LPWSAOVERLAPPED lpOverlapped,
	DWORD dwFlags){
    
    //does not work, how to pass context info?
    auto* obj = static_cast<context_obj*>(lpOverlapped.hEvent);
    
    }

不知道是不是我理解的有问题,这样传递 context 不行。 求教。

1882 次点击
所在节点    C
8 条回复
ysc3839
2018-10-29 16:43:19 +08:00
能否提供更详细的信息?你说不行是怎么个不行?
v2byy
2018-10-29 17:27:07 +08:00
@ysc3839 就是在 completionCallback 中,我强制转化的 obj 并不是 context_obj 类型。我想是不是我理解错了,这个 msdn 中 hEvent 可以作为传递参数的意思。貌似并没有传递过来。
ysc3839
2018-10-29 18:09:07 +08:00
@v2byy 能把完整代码发来看看吗?
zealot0630
2018-10-29 18:56:04 +08:00
LPWSAOVERLAPPED 是一个指针,你访问他的成员时候为什么可以用 .
zealot0630
2018-10-29 18:57:50 +08:00
另外 转换指针应该用 reinterpret_cast 而不是 static_cast
v2byy
2018-10-30 09:19:33 +08:00
v2byy
2018-10-30 09:20:48 +08:00
@zealot0630 嗯,笔误了,指针转换确实要用 reinterpret_cast,多谢
v2byy
2018-10-31 09:33:10 +08:00
顶一下,没有大佬来解答一下么

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/502208

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX