V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
v2byy
V2EX  ›  C

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

  •  
  •   v2byy · 2018-10-29 15:20:07 +08:00 · 1874 次点击
    这是一个创建于 1977 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在使 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 不行。 求教。

    8 条回复    2018-10-31 09:33:10 +08:00
    ysc3839
        1
    ysc3839  
       2018-10-29 16:43:19 +08:00 via Android
    能否提供更详细的信息?你说不行是怎么个不行?
    v2byy
        2
    v2byy  
    OP
       2018-10-29 17:27:07 +08:00
    @ysc3839 就是在 completionCallback 中,我强制转化的 obj 并不是 context_obj 类型。我想是不是我理解错了,这个 msdn 中 hEvent 可以作为传递参数的意思。貌似并没有传递过来。
    ysc3839
        3
    ysc3839  
       2018-10-29 18:09:07 +08:00 via Android
    @v2byy 能把完整代码发来看看吗?
    zealot0630
        4
    zealot0630  
       2018-10-29 18:56:04 +08:00
    LPWSAOVERLAPPED 是一个指针,你访问他的成员时候为什么可以用 .
    zealot0630
        5
    zealot0630  
       2018-10-29 18:57:50 +08:00
    另外 转换指针应该用 reinterpret_cast 而不是 static_cast
    v2byy
        7
    v2byy  
    OP
       2018-10-30 09:20:48 +08:00
    @zealot0630 嗯,笔误了,指针转换确实要用 reinterpret_cast,多谢
    v2byy
        8
    v2byy  
    OP
       2018-10-31 09:33:10 +08:00
    顶一下,没有大佬来解答一下么
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1014 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 19:56 · PVG 03:56 · LAX 12:56 · JFK 15:56
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.