임베디드

BCM(Broadcom) SDK를 보다가...

트릭맨 2011. 2. 17. 13:15
bcm api를 보다가 갑자기 소스가 이해가 되질 않았다..특히 BCM_DLIST_ENTRY...
$BCM_HOME/bcm/src/dispatch.c 파일에서 분명히 호츨을 하는 것 같긴 한데...
그 다음이 이해가 되질 않았다..그냥 넘어갈 수도 있었지만 나름대로 해석을 해야 할 것
같아서 소스를 간추렸다..

----------------8<--- Cut Here --->8-------------------
$ more abc.c
#include <stdio.h>

#define BCM_DLIST_ENTRY(_dtype) \
        extern int bcm_##_dtype##_add(int i, int j);
#include "dlist.h"

#define BCM_DLIST_ENTRY(_dtype) \
bcm_##_dtype##_add,
static int (*_port_add_dispatch[])(
        int i,
        int j ) =
{
#include "dlist.h"
0
};

int
bcm_port_add(int i, int j)              <- application에서 이 함수를 호출했다 치고..
{
    _port_add_dispatch[0](i, j);         <- 요기부터 이해가 안되었다...
                                 위의 파란색을 보면 분명히 BCM_DLIST_ENTRY가 2개나 보이는데
                                 duplication에러도 없고 도데체 어떻게 해석이 되는지 알 수가 없었다.
}
----------------8<--- Cut Here --->8-------------------
$ more dlist.h
#ifdef BCM_DLIST_ENTRY

BCM_DLIST_ENTRY(esw)

#undef BCM_DLIST_ENTRY

#endif
----------------8<--- Cut Here --->8-------------------
$ more add.c
#include <stdio.h>

int
bcm_esw_add(int i, int j)
{
    printf("F=[%s] arg1=[%d],arg2=[%d]\n", __FUNCTION__, i, j);
}
----------------8<--- Cut Here --->8-------------------

나름대로 이해를 하기 위해서 헤더파일을 소스 파일에 넣었다...
그랬더니 조금 이해하기가 쉬웠다...

----------------8<--- Cut Here --->8-------------------
#define BCM_DLIST_ENTRY(_dtype) \       <- BCM_DLIST_ENTRY define한다.
    extern int bcm_##_dtype##_add(int i, int j);
#ifdef BCM_DLIST_ENTRY                  <- define되어 있으므로 아래를 아래 문장을 interpret 해라
BCM_DLIST_ENTRY(esw)                    <- extern int ... 라인을 interpret
#undef BCM_DLIST_ENTRY                  <- 다시 undef
#endif

#define BCM_DLIST_ENTRY(_dtype) \       <- 다시 define
bcm_##_dtype##_add,                
static int (*_port_add_dispatch[])(     <- 아래 bcm_port_add 함수안에서 사용하는 함수포인터의 
    int i,                                 진짜 함수(extern)를 지정하기 위해서
    int j ) =
{
#ifdef BCM_DLIST_ENTRY                  <- 방금 위에서 define했으므로 아래 문자을 interpret
BCM_DLIST_ENTRY(esw)                    <- bcm_..._add 가 여기에 들어간다.
#undef BCM_DLIST_ENTRY                  <- 그리고 다시 undef
#endif
0
};

int
bcm_port_add(int i, int j)
{
    _port_add_dispatch[0](i, j);        <- 0번째 함수를 call 해라
}
----------------8<--- Cut Here --->8-------------------

그리고 마지막으로 정리를 하니까...이렇게 간단하게 정리가 되었다...
----------------8<--- Cut Here --->8-------------------
extern int bcm_esw_add(int i, int j);

static int (*_port_add_dispatch[])(
        int i,
        int j ) =
{
        bcm_esw_add,
        0
};

int
bcm_port_add(int i, int j)
{
        _port_add_dispatch[0](i, j);
}
----------------8<--- Cut Here --->8-------------------