Biff
Biff

Reputation: 1039

Function Name Variability with Pointer in Struct

The pointers function declarations in the following snippets of code allows me to vary the names of each function inside the struct, correct? This is merely hypothetical, so the names are of no consequence yet.

Header File

typedef struct
{
    bool (*enabled)(uint32_void);
    void (*start)(uint32_t);
    void (*stop)(uint32_t);
    bool (*expired)(void);
} battle_star_gallactica;

C File

static bool Battle_v0_enabled (void) { ... }
static void Battle_v0_start (uint32_t) { ... }
static void Battle_v0_stop (uint32_t) { ... }
static bool Battle_v0_stop (void) { ... }

const battle_star_gallactica battle_v0 =
{
    enabled,
    start,
    stop,
    expired
};
...

One Example Use

battle_v0.start(1000);

The C file snippet would be repeated for other versions (e.g. v1 or v2 instead of v0).

How does this work?

EDIT

Corrected code:

Header File

typedef struct
{
    bool (*enabled)(uint32_void);
    void (*start)(uint32_t);
    void (*stop)(uint32_t);
    bool (*expired)(void);
} battle_star_gallactica;

extern const battle_star_gallactica battle_v0;
extern const battle_star_gallactica battle_v1;
...

C File

static bool Battle_v0_enabled (void) { ... }
static void Battle_v0_start (uint32_t val) { ... }
static void Battle_v0_stop (uint32_t val) { ... }
static bool Battle_v0_expired (void) { ... }

const battle_star_gallactica battle_v0 =
{
    Battle_v0_enabled,
    Battle_v0_start,
    Battle_v0_stop,
    Battle_v0_expired
};
...

One Example Use

battle_v0.start(1000);

Upvotes: 0

Views: 109

Answers (3)

John Bode
John Bode

Reputation: 123458

You have to assign the target function to each of your function pointers, such as

battle_v0.enabled = Battle_V0_enabled;
battle_v0.start   = Battle_V0_start;
// etc.

or

const battle_star_galactica battle_v0 = {
    Battle_V0_enabled,
    Battle_V0_start,
    Battle_V0_stop,
    Battle_V0_expired
};

Then you can call the functions through the pointer:

battle_v0.start(1000);  // or battle_v0.(*start)(1000)

will call the Battle_V0_start function with a value of 1000.

Note that the function signatures (return type and number/types of arguments) have to match; for example, you declare the function pointer for start to take an argument of type uint32_t, but Battle_V0_start takes no arguments. One or the other of these needs to change so that they match.

void Battle_V0_start(uint32_t val) { ... }

Upvotes: 1

Richard Schneider
Richard Schneider

Reputation: 35477

Yes. But you have a few issues:

1) Battle_v0_stop is defined twice 2) When initing battle_v0 you need to prefix values with Battle_v0_

You could then do:

battle_v0.enabled()

But I would have currnet battle star galactic and use it:

const battle_star_gallactica bsg = battle_v0;
bgs.enabled()

Upvotes: 2

RageD
RageD

Reputation: 6823

You have no functions named enabled, start, and so on. When initializing an object with function pointers, pass a pointer to the actual function name (i.e. Battle_v0_start). That said, it is important to notice that your types do not match. It should be Battle_v0_start(uint32_t), not void.

But yes, after being properly initialized, you will be able to simply call your_obj.your_struct_function_name(your_arguments, ...). In your case battle_v0.start(1000) will call Battle_v0_start (if you pass this function to the pointer). You can think of this like most other pointer types.

Upvotes: 1

Related Questions