LiteOS LOS_DL_LIST_ENTRY 巨集定義
#define LOS_DL_LIST_ENTRY(item, type, member) \ ((type *)((char *)item - LOS_OFF_SET_OF(type, member))) \
首先來確定LOS_OFF_SET_OF是什麼
#define LOS_OFF_SET_OF(type, member) ((long)&((type *)0)->member)
把型別強制轉換為0,然後取成員member的地址。最後在轉換為long。
問題來了,為什麼要轉換為0?
因為這裡是計算member針對這個型別的偏移地址,轉換為0之後,直接可以得到member的偏移地址。
#define LOS_DL_LIST_ENTRY(item, type, member) \
((type *)((char *)item - LOS_OFF_SET_OF(type, member))) \
這裡是計算型別的首地址。對於結構體來說,這個結構體的地址就是成員的首地址
舉例:osTaskScan函式
for (pstTaskCB = LOS_DL_LIST_ENTRY((pstListObject)->pstNext, LOS_TASK_CB, stTimerList);&pstTaskCB->stTimerList != (pstListObject);)
其中item =(pstListObject)->pstNext;
type =LOS_TASK_CB;
member =stTimerList;
typedef struct tagTaskCB
{
VOID *pStackPointer; /**< Task stack pointer */
UINT16 usTaskStatus;
.....
LOS_DL_LIST stTimerList;
VOID *puwMsg; /**< Memory allocated to queues */
} LOS_TASK_CB;
通過LOS_OFF_SET_OF可以計算出stTimerList到pStackPointer的偏移量
pstListObject->pstNext經過巨集轉換得到一個地址,這個地址就是member的地址,然後減去member的偏移量,就是結構體的首地址了