admin管理员组

文章数量:1289957

Can anyone please help me with how to pass a function to a function pointer inside struct in C? I have a function as below

typedef struct LOAD_DRV_DATA
{
   uint8_t LoadDrvId;
   uint8_t dataLength;
   uint8_t DataBuffer[8];
}LOAD_DRV_DATA;

typedef struct LOAD_DRV_MAP
{
    uint8_t rspRemoteNum;
    uint8_t loadDrvID;
    uint8_t loadDrvComIf;
    void (*loadDrvFnPtr)(void);
}LOAD_DRV_MAP;
        
void LoadDrv_writeConfigData(LOAD_DRV_DATA *configData)
{
   uint8_t chipSel = 0x00;
   uint8_t buff    = 0xFF;
   LOAD_DRV_MAP configLoadDrvMap;
   
   configLoadDrvMap.rspRemoteNum = configData->LoadDrvId;
   configLoadDrvMap.loadDrvFnPtr = &write_SpiConfig(configLoadDrvMap.rspRemoteNum, chipSel, buff);
}

I have a structure member called loadDrvFnPtr to which I have to assign the function. This has to be void because more functions will be assigned to this with different arguments so that the basic data type kept is void.

Can anyone please help me with how to pass a function to a function pointer inside struct in C? I have a function as below

typedef struct LOAD_DRV_DATA
{
   uint8_t LoadDrvId;
   uint8_t dataLength;
   uint8_t DataBuffer[8];
}LOAD_DRV_DATA;

typedef struct LOAD_DRV_MAP
{
    uint8_t rspRemoteNum;
    uint8_t loadDrvID;
    uint8_t loadDrvComIf;
    void (*loadDrvFnPtr)(void);
}LOAD_DRV_MAP;
        
void LoadDrv_writeConfigData(LOAD_DRV_DATA *configData)
{
   uint8_t chipSel = 0x00;
   uint8_t buff    = 0xFF;
   LOAD_DRV_MAP configLoadDrvMap;
   
   configLoadDrvMap.rspRemoteNum = configData->LoadDrvId;
   configLoadDrvMap.loadDrvFnPtr = &write_SpiConfig(configLoadDrvMap.rspRemoteNum, chipSel, buff);
}

I have a structure member called loadDrvFnPtr to which I have to assign the function. This has to be void because more functions will be assigned to this with different arguments so that the basic data type kept is void.

Share Improve this question edited Feb 20 at 10:33 Fatpanda asked Feb 20 at 10:06 FatpandaFatpanda 615 bronze badges 10
  • 2 It would be something like configLoadDrvMap.loadDrvFnPtr = name_of_function; but there will be a type mismatch if the function prototypes do not match. It is possible to cast a function pointer value to another function pointer type and back again, and it will compare equal to the original function pointer value. The important thing is that when calling a function, the prototype of the possibly converted and dereferenced pointer needs to match the prototype of the function being called. – Ian Abbott Commented Feb 20 at 10:25
  • yes, i agree that's what i was looking for but not really sure how to do this. – Fatpanda Commented Feb 20 at 10:28
  • To follow up my previous comment, you can cast the function pointer value prior to assignment like this: configLoadDrvMap.loadDrvFnPtr = (void (*)(void))name_of_function;, and cast it back to the correct type before calling the function. I don't know the type of your function, but it would be something like void (*fp)(uint_8, uint_8, void *) = ((void (*)(uint8_t, uint8_t, void *))pLoadDrvMap->loadDrvFnPtr; fp(pLoadDrvMap->rspRemoteNum, chipSel, buff);. – Ian Abbott Commented Feb 20 at 10:35
  • @IanAbbott Not sure if wild casting is proper advice here (or, rather: I'm pretty much sure it isn't) – tofro Commented Feb 20 at 10:42
  • 1 Completely unrelated to your question, consider adopting a consistent coding style. You are using some hybrid of CamelCase and snake_case and also capitalize identifiers inconsistently. ALL CAPS is usually reserved for constants and macros. Etc. C programmers tend to prefer snake_case and it's even been proven easier to read, but that's ofc a subjective coding style matter. The most important is that you are using a style consistently. – Lundin Commented Feb 20 at 10:58
 |  Show 5 more comments

2 Answers 2

Reset to default 2

You have to separate the function pointer assignment and the function call.

It should just be configLoadDrvMap.loadDrvFnPtr = &write_SpiConfig;. In your code you are attempting to call the function at the same line as you assign the function pointer and that's not going to work - you'd end up assigning the function pointer to the result of the function call and the compiler will protest with some error message about incompatible types.


Best practices:

  • Using function pointers without typedef is bad style, since they quickly get hard to read.

  • Use a function pointer syntax similar to object pointer syntax for style consistency.

  • As a rule of thumb: good variable names explain what the variable does, not what the variable is.

    Variable names containing too much info about what type that variable has (ie FnPtr) is an indication of muddy design and lead to needless clutter. Programmers are expected to always look up the type of a variable before using it.

Example of how to fix the above:

typedef void load_drv_t (void); // function type

...

typedef struct LOAD_DRV_MAP
{
  ...
  load_drv_t* load_drv; // pointer to load_drv_t, quite self-documenting
}LOAD_DRV_MAP;

...

configLoadDrvMap.load_drv = &write_SpiConfig;

There's simply too much wrong to answer this question with proper code:

You didn't use the structure in your assignment at all. It should look something like

  configLoadDrvMap.loadDrvFnPtr = write_SpiConfig;

This might, however, need a type cast depending on what exactly write_SpiConfigis and is likely wrong anyways because your function pointer in the structure expects a void (*)(void) and you are assigning a pointer to a non-void function that expects arguments.

Also, your use of arguments in the function pointer assignment hints you are understanding this as a function call - it isn't.

本文标签: cWhat is the correct way to assign function to a function pointer of a structure memberStack Overflow