amanuel2
amanuel2

Reputation: 4646

How to define a struct function in a source file or struct itself

I'm confused about how I define a struct function in a source file or in the struct itself. Yes I have read a similar Stack Overflow question, but that asks if you can define a function declared in the struct itself. Basically in simple matters, I have this "NetworkDriver" struct:

typedef struct
{
    char *name;
    bool initialized;
    int32_t status;
    int (*initialize)(void);
} NetworkDriver;

As you can see, I'm trying to define the function pointer that has been initialized in the struct. How do we go about doing this?

Upvotes: 1

Views: 211

Answers (3)

sps
sps

Reputation: 2720

Below is what I could get closest to what you are telling. I made some change (used int instead of bool), and also added one more function pointer in your NetworkDriver structure, and added parameters to the functions.

However, it seems you want each instance of NetworkDriver have its own initialize function. But what I have done is I have defined the initialize function once, and each instance of NetworkDriver have a pointer to it. Not exactly like what you are saying, but this is what I could think of.

As dxib has mentioned in his answer, the functions will still have to be explicitly called. I is not something like a constructor in C++. Also before calling, these functin pointers inside the structure have to be assigned the address of functions explicitly.

#include<stdio.h>
#include<stdlib.h>

#define TRUE  1
#define FALSE 0

#define NO_ERR          10
#define NAME_ERR        11
#define INITIALIZED_ERR 12

typedef struct
{
    char *name;
    int initialized;
    int32_t status;
    int (*initialize)(void *, char *); 
    void (*disp_info)(void *); /* Note: one more func pointer */
}NetworkDriver;


/* Function prototype declarations */
int nd_init(void *ndr, char *name);
void nd_disp_info(void *ndr);

/* main: test NetworkDriver and nd_init */
int main(void)
{
    NetworkDriver nd; 

    nd.initialized = FALSE;
    nd.initialize = nd_init;
    nd.disp_info = nd_disp_info;

    if (nd.initialize(&nd, "foo")) { /* Initialize driver */
            printf("Error: Initialization error\n");
            exit(1);
    }

    nd.disp_info(&nd);  /* display nd's info */

/* nd_init: initialize a NetworkDriver */
int nd_init(void *ndr, char *name)
{
    NetworkDriver *nd;

    nd = (NetworkDriver *) ndr;

    if (!(nd->name = name)) {
            nd->status = NAME_ERR;
            return 1;
    }


    if (nd->initialized != TRUE) {
            if (!(nd->initialized = TRUE)) {
                    nd->status = INITIALIZED_ERR;
                    return 1;
            }
    }


    /* Successfully initialized */
    nd->status = NO_ERR;
    return 0;
}

/* nd_disp_info: display NetworkDriver info  */
void nd_disp_info(void *ndr)
{
    NetworkDriver *nd;

    nd = (NetworkDriver *) ndr;

    /* If this driver was not initialized without err */
    if (nd->status != NO_ERR) {
            printf("NetworkDriver was not initialized correctly\n");
            return;
    }

    /* Print info */
    printf("=== NetworkDriver info ===\n");
    printf("Name: %s\n", nd->name);
    printf("Initialized ? %s\n", nd->initialized == TRUE ? "TRUE" :
                           "FALSE");
    printf("Status: %d\n", (int) nd->status);
}

Upvotes: 0

Aganju
Aganju

Reputation: 6395

Not sure if I get the problem; what you did in your code fragment was declaring a type. There is no instance of this type yet that you could initialize; you need to declare an instance; either by adding it to the line at the end: }NetworkDriver var;, or by adding another line afterwards: NetworkDriver var;.

Either way, you can initialize this instance by adding ={"whatever",true,0,&function} to it; or specifically only that function pointer by adding a further line var.initialize = &funciton;.

Upvotes: 0

dxiv
dxiv

Reputation: 17638

The question being tagged as C (not C++) it should be noted that there is no such thing as a struct function in C. In the given code snippet, initialize is simply a data member of the struct typedef'd as NetworkDriver declared to be a pointer to a function that takes no arguments and returns an int.

The mechanics of defining and using the variable are the same as for any function pointer: it must be set to point to a function with the given prototype, then it can be called with the usual function syntax.

#include <stdio.h>

typedef struct
{
    int (*initialize)(void);
} NetworkDriver;

int init(void)
{
    printf("initializing...\n");
    return 0;
}

int main(void)
{
    NetworkDriver nd;
    nd.initialize = init;

    nd.initialize(); // prints 'initializing...'

    return 0;
}

Upvotes: 3

Related Questions