//已知链表地址,怎么得到链表所属的结构体的地址.
pOpenHead = CONTAINING_RECORD( pEntry, HW_OPEN_INFO, llist);
//链表类型为llist,所属上层结构体为HW_OPEN_INFO,pEntry就是已分配内存的链表的地址
/*
#define CONTAINING_RECORD(address, type, field) ((type *)( \
(LPBYTE)(address) - \
(LPBYTE)(&((type *)0)->field)))
*/
/*
typedef struct __HW_OPEN_INFO {
PHW_INDEP_INFO pSerialHead; // @field Pointer back to our HW_INDEP_INFO
DWORD AccessCode; // @field What permissions was this opened with
DWORD ShareMode; // @field What Share Mode was this opened with
DWORD StructUsers; // @field Count of threads currently using struct.
COMM_EVENTS CommEvents; // @field Contains all info for serial event handling
LIST_ENTRY llist; // @field Linked list of OPEN_INFOs
} HW_OPEN_INFO, *PHW_OPEN_INFO;
*/
//链表怎么初始化和 插入的: 答链表头必须要用InitializeListHead初始化,要插入的节点不需要,
typedef struct _LIST_ENTRY {
struct _LIST_ENTRY * Flink;
int a;
struct _LIST_ENTRY * Blink;
} LIST_ENTRY,*PLIST_ENTRY;
EX_ListHead是一个_LIST_ENTRY结构体变量,那么EX_ListHead.Flink和EX_ListHead.Flink->Blink代表什么?
答:EX_ListHead.Flink和代表一个_LIST_ENTRY类型的指针,这个指针站4个字节位于EX_ListHead变量的空间内,
EX_ListHead.Flink->Blink,如果令EX_ListHead.Flink=X, 那么EX_ListHead.Flink->Blink相当于X.Blink
//定义2个变量
LIST_ENTRY OpenList; // @field Head of linked list of OPEN_INFOs
LIST_ENTRY llist;
LIST_ENTRY llist2;
InitializeListHead( &OpenList );
InsertHeadList(&OpenList,&llist);
//他们2个关系如图
InsertHeadList(&OpenList,&llist2);
//他们3个关系如图:
附录:
#define InitializeListHead(ListHead) \
((ListHead)->Flink = (ListHead)->Blink = (ListHead) )
#define IsListEmpty(ListHead) \
(( ((ListHead)->Flink == (ListHead)) ? TRUE : FALSE ) )
#define RemoveHeadList(ListHead) \
(ListHead)->Flink;\
{\
PLIST_ENTRY FirstEntry;\
FirstEntry = (ListHead)->Flink;\
FirstEntry->Flink->Blink = (ListHead);\
(ListHead)->Flink = FirstEntry->Flink;\
}
#define RemoveEntryList(Entry) do {\
PLIST_ENTRY _EX_Entry;\
_EX_Entry = (Entry);\
_EX_Entry->Blink->Flink = _EX_Entry->Flink;\
_EX_Entry->Flink->Blink = _EX_Entry->Blink;\
} while(0);
_inline
PLIST_ENTRY
RemoveTailList(PLIST_ENTRY ListHead)
{
PLIST_ENTRY _Tail_Entry;
_Tail_Entry = ListHead->Blink;
RemoveEntryList(_Tail_Entry);
return _Tail_Entry;
}
#define InsertTailList(_ListHead,_Entry) do {\
PLIST_ENTRY _EX_ListHead = _ListHead; \
PLIST_ENTRY _EX_Blink = _EX_ListHead->Blink; \
(_Entry)->Flink = _EX_ListHead; \
(_Entry)->Blink = _EX_Blink; \
_EX_Blink->Flink = _Entry; \
_EX_ListHead->Blink = _Entry; \
} while(0);
#define InsertHeadList(_ListHead,_Entry) do {\
PLIST_ENTRY _EX_ListHead = _ListHead; \
PLIST_ENTRY _EX_Flink = _EX_ListHead->Flink; \
(_Entry)->Flink = _EX_Flink; \
(_Entry)->Blink = _EX_ListHead; \
_EX_Flink->Blink = _Entry; \
_EX_ListHead->Flink = _Entry; \
} while (0);