-1

Calling a function without calling its parameters inside another function is a little bit confusing as follows:

ppp = pppos_create(&ppp_netif, output_cb, status_cb, 0);

Where output_cb and status_cb are functions that their parameters are not set and their definitions must be written in upper lines than the line they are called.

Function definitions:

static void status_cb(ppp_pcb *pcb, int err_code, void *ctx) {

    struct netif *pppif = ppp_netif(pcb);

    switch(err_code) {
        case PPPERR_NONE: {
            printf("status_cb: Connected\n");
            printf("   our_ipaddr  = %s\r\n", ipaddr_ntoa(&pppif->ip_addr));
            printf("   his_ipaddr  = %s\r\n", ipaddr_ntoa(&pppif->gw));
            printf("   netmask     = %s\r\n", ipaddr_ntoa(&pppif->
            break;
        }
        case PPPERR_PARAM: {
            printf("status_cb: Invalid parameter\r\n");
            break;
        }
    }
}

static u32_t output_cb(ppp_pcb *pcb, u8_t *data, u32_t len, void *ctx)
{
    return HAL_UART_Transmit_IT(&huart1, data, sizeof(data));
}

int main(void)
{
    ppp = pppos_create(&ppp_netif, output_cb, status_cb, 0);
}

What does status_cb print without giving an err_code as a parameter? When or how will status_cb and output_cb be evaluated?

Where pppos_createis defined as follows:

ppp_pcb *pppos_create(struct netif *pppif, pppos_output_cb_fn output_cb,
       ppp_link_status_cb_fn link_status_cb, void *ctx_cb)
{
    pppos_pcb *pppos;
    ppp_pcb *ppp;

    pppos = (pppos_pcb *)LWIP_MEMPOOL_ALLOC(PPPOS_PCB);
    if (pppos == NULL) {
        return NULL;
    }

    ppp = ppp_new(pppif, &pppos_callbacks, pppos, link_status_cb, ctx_cb);
    if (ppp == NULL) {
        LWIP_MEMPOOL_FREE(PPPOS_PCB, pppos);
        return NULL;
    }

    memset(pppos, 0, sizeof(pppos_pcb));
    pppos->ppp = ppp;
    pppos->output_cb = output_cb;
    return ppp;
}

Kind Regards

too honest for this site
  • 12,050
  • 4
  • 30
  • 52

1 Answers1

2

Calling a function without calling its parameters inside another function is a little bit confusing as follows:

ppp = pppos_create(&ppp_netif, output_cb, status_cb, 0);

Where output_cb and status_cb are functions [...]

output_cb and status_cb are not function calls, but rather function pointers. A function's name without the parenthesised parameter list is a pointer to the function not a call to it. A function pointer allows a function to be called without knowledge of which function will be called at compile/link time. In this case that are used as callbacks so that a predefined library function can call a user application function.

A simple example of a function pointer:

Given:

int someFunction( int arg ) 
{
    return( arg ) ;
}

The you can declare a function pointer fp variable thus:

int (*fp)(int) = someFunction ;

You can then call someFunction function through fp thus:

int x = fp( 2 ) ;

What does status_cb print without giving an err_code as a parameter? When or how will status_cb and output_cb be evaluated?

The arguments to the functions are provided at the time they are called, not the time they are passed to pppos_create(). In pppos_create(), they are assigned to the output_cb and ,link_status_cbparameters respectively. They have typepppos_output_cb_fnandppp_link_status_cb_fnwhich will betypedef`s for function pointer types for example:

typedef void (*ppp_link_status_cb_fn)(ppp_pcb *, int, void*);

In this case pppos_create() does not call these functions; rather it is assigning them to members of data structures pppos and ppp which will presumably be called later whenever the associated PPP events occur (I am guessing that this is a point-to-point protocol related function). In this case they are a way of providing user defined handling to a pre-defined function.

Clifford
  • 88,407
  • 13
  • 85
  • 165
  • Sir, thank you very much for paying attention and giving a full answer that erases all the questions about the function pointers in the most general way; however, I am setting a variable depending on the switch case in the `output_cb` function and realized that it is never been set. Is it why that I am not able to properly create the PPPoS session or the associated PPP event never occurs? More specifically, how may I know which associated event calls that `output_cb` function; so that I will not have to debug since GSM modem will not break out the connection? – Sarp Engin Daltaban May 11 '18 at 09:25
  • Additionally, I have to check the error code globally and I even cannot assign it to `output_cb`. How will I be able to see that error code and do process according to it? Kind Regards – Sarp Engin Daltaban May 11 '18 at 09:31
  • @SarpEnginDaltaban : You have gone from a very general question about function pointers to very specific questions about an API. You would do better to post a new question about these issues. Passing an initialised callback pointer to an API is unlikely to end well. – Clifford May 11 '18 at 09:45