проблема приведения со связанным элементом списка

Это моя структура 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->, не могут использоваться в этом случае.

Есть ли способ справиться с этой ситуацией?

0

Решение

Чтобы получить адрес соответствующей структуры 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

2

Другие решения

Я не уверен, есть ли поддерживаемый механизм для преобразования указателя на член структуры в указатель на структуру. Вы мог бросить все на 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;
1

По вопросам рекламы [email protected]