2014-01-05 15 views
0

铸造的问题这是我PER_IO_CONTEXT结构(我将它们存储在单链表):与链表项

typedef struct _PER_IO_CONTEXT 
{ 

    SLIST_ENTRY  ItemEntry; 
    WSAOVERLAPPED  Overlapped; 
    WSABUF     wsabuf; 
    /* some other data*/ 

} PER_IO_CONTEXT, *PPER_IO_CONTEXT; 

及以下WSAsend,使用该名单获得WSAOVERLAPPED结构:

... 
PSLIST_HEADER pListHead; 
... 

PSLIST_ENTRY pListEntry = InterlockedPopEntrySList(pListHead); 
PPER_IO_CONTEXT ovl = (PPER_IO_CONTEXT)pListEntry; 
WSASend(pTmp1->Socket,..., &(ovl->Overlapped), NULL); 

当GQCS得到最后通知:

LPWSAOVERLAPPED lpOverlapped = NULL; 
PPER_IO_CONTEXT lpIOContext = NULL; 
.... 
GetQueuedCompletionStatus(..... (LPOVERLAPPED *)&lpOverlapped, INFINITE); 
lpIOContext = (PPER_IO_CONTEXT)lpOverlapped; 
lpIOContext->wsabuf  // this fail 

正如你可以看到下列投lpIOContext =(PPER_IO_CONTEXT)lpOverlapped不起作用,因为WSAsend提供了wsaoverlapped - PER_IO_CONTEXT结构的第二个成员,所以在这种情况下不能使用像lpIOContext->这样的引用。

有办法处理这种情况吗?

回答

2

要得到相应的PER_IO_CONTEXT的地址结构您可以使用此:

lpIOContext = CONTAINING_RECORD(lpOverlapped, PER_IO_CONTEXT, Overlapped); 

CONTAINING_RECORD就是以这样的方式在VC\crt\src\collections.h定义一个宏:

#define CONTAINING_RECORD(address, type, field) \ 
    ((type *)((char *)(address) - (ULONG_PTR)(&((type *)0)->field))) 

的更多信息:http://msdn.microsoft.com/en-us/library/windows/hardware/ff542043%28v=vs.85%29.aspx

+0

完成这个任务没有你的帮助,我会应付不来, 谢谢。 – maciekm

1

我不确定是否有支持的机制将指针转换为结构成员指向结构的指针。您可以投一切BYTE *,做算术,这将在实际工作中,但根据您的需求,它可能是更清洁重组,以避免必要性:

typedef struct _PER_IO_CONTEXT 
{ 
    WSAOVERLAPPED  Overlapped; 
    WSABUF     wsabuf; 
    /* some other data*/ 
} PER_IO_CONTEXT, *PPER_IO_CONTEXT; 

typedef struct _PER_IO_CONTEXT_LIST_ITEM 
{ 
    SLIST_ENTRY  ItemEntry; 
    PER_IO_CONTEXT Item; 
} PER_IO_CONTEXT_LIST_ITEM, *PPER_IO_CONTEXT_LIST_ITEM; 
+0

如果你去指针运算路线,看到http://msdn.microsoft.com/en-us/library/dz4y9b9a.aspx –