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

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

  •  
  •   v2byy · 205 天前 · 473 次点击
    这是一个创建于 205 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在使 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
        1
    ysc3839   205 天前 via Android
    能否提供更详细的信息?你说不行是怎么个不行?
        2
    v2byy   205 天前
    @ysc3839 就是在 completionCallback 中,我强制转化的 obj 并不是 context_obj 类型。我想是不是我理解错了,这个 msdn 中 hEvent 可以作为传递参数的意思。貌似并没有传递过来。
        3
    ysc3839   205 天前 via Android
    @v2byy 能把完整代码发来看看吗?
        4
    zealot0630   205 天前
    LPWSAOVERLAPPED 是一个指针,你访问他的成员时候为什么可以用 .
        5
    zealot0630   205 天前
    另外 转换指针应该用 reinterpret_cast 而不是 static_cast
        7
    v2byy   205 天前
    @zealot0630 嗯,笔误了,指针转换确实要用 reinterpret_cast,多谢
        8
    v2byy   204 天前
    顶一下,没有大佬来解答一下么
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3931 人在线   最高记录 5043   ·  
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 18ms · UTC 07:02 · PVG 15:02 · LAX 00:02 · JFK 03:02
    ♥ Do have faith in what you're doing.
    沪ICP备16043287号-1