1. 程式人生 > 實用技巧 >LiteOS LOS_DL_LIST_ENTRY 巨集定義

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的偏移量,就是結構體的首地址了