Question

Please give me some examples of jump table usage. I have seen this example on wikipedia:

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

typedef void (*Handler)(void);    /* A pointer to a handler function */



/* The functions */
void func3 (void) { printf( "3\n" ); }
void func2 (void) { printf( "2\n" ); }
void func1 (void) { printf( "1\n" ); }
void func0 (void) { printf( "0\n" ); }



Handler jump_table[4] = {func0, func1, func2, func3};



int main (int argc, char **argv) {
    int value;

    /* Convert first argument to 0-3 integer (Hash) */
    value = atoi(argv[1]) % 4;
    if (value < 0) {
        value *= -1;
    }

    /* Call appropriate function (func0 thru func3) */
    jump_table[value]();
}

But I was wondering if there is an alternate way of calling the function instead of using index as shown, in the above case it is jump_table[value]();

What I want to achieve is, instead of using the index is there a way to use the name of the function itself.

For example, say we have all the function pointers in a struct.

typedef struct _funcptrs
{
  void func1();
  void func2();
} funcptrs;

and now when I want to call the function can I do something like funcptrs.func1() ?

Was it helpful?

Solution

Certainly, but you need to declare them as function pointers and initialize them first. Though this defeats the purpose of a jump table if you have to spell out the function name.

e.g.

#include <stdio.h>

void func1 (void) { printf( "1\n" ); }
void func0 (void) { printf( "0\n" ); }

typedef struct
{
  void (*func0)(void);
  void (*func1)(void);
}  funcptrs;

int main(int argc, char *argv[])
{
   funcptrs funcs = { func0, func1 };
   funcs.func1();
   return 0;
}

If you need to call the function by having the name of the function as a string, you need to create a mapping between the functions name and a function pointer, then search the table for that function, and call it.

#include <stdio.h>
#include <string.h>

void func1 (void) { printf( "1\n" ); }
void func0 (void) { printf( "0\n" ); }

#define DEFUN(name) { #name, name }

typedef struct
{
  const char *name;
  void (*func)(void);
}  funcptrs;

void call(funcptrs *ptrs, const char *name)
{
    int i;
    for(i = 0; ptrs[i].name; i++) {
      if(strcmp(ptrs[i].name, name) == 0) {
           ptrs[i].func();
           break;
       }
    }
}
int main(int argc, char *argv[])
{
   funcptrs funcs[] = {DEFUN(func0), DEFUN(func1), {NULL,NULL}};
   call(funcs, "func0");
   return 0;
}

OTHER TIPS

You can certainly create a struct containing pointers to functions. There are even good reasons to do so.

For one example, consider the interface between an operating system and a device driver of some sort. Simplifying a lot, this might look something on this order:

struct device { 
    int (*open)(unsigned mode);
    int (*close)(void);
    int (*read)(void *buffer, size_t size);
    int (*write)(void *buffer, size_t size);
};

Then an individual device driver would create a struct of this type, and initialize the individual pointers to refer to the functions relevant to a particular device:

struct device serial_port = { 
    open_serial,
    close_serial,
    read_serial,
    write_serial
};

struct device ethernet_adapter = { 
    open_net,
    close_net,
    read_net,
    write_net
};

struct device keyboard = { 
    open_keyboard,
    close_keyboard,
    read_keyboard,
    NULL  // we'll assume no writing to the keyboard...
};

Then some higher-level function can receive one of these, and open/close/read/write some device without having to know the exact identity of the device involved. Of course, for a real OS, it gets a bit more complex than this but the general idea is (or at least can be) fairly similar.

You can use an enum to represent the indices of your array and give them meaningful names for you.

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

typedef void (*Handler)(void);    /* A pointer to a handler function */

/* The functions */
void func3 (void) { printf( "3\n" ); }
void func2 (void) { printf( "2\n" ); }
void func1 (void) { printf( "1\n" ); }
void func0 (void) { printf( "0\n" ); }

enum{
    FUNC0,
    FUNC1,
    FUNC2,
    FUNC3
};

Handler jump_table[4] = {func0, func1, func2, func3};

int main (int argc, char **argv) {
    /* Call appropriate function (func0 thru func3) */
    jump_table[FUNC0]();
    jump_table[FUNC1]();
    jump_table[FUNC2]();
    jump_table[FUNC3]();
    return 0;
}

This will output

0
1
2
3
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top