View Full Version : [SOLVED] C - Call function when name in variable
bobbocanfly
September 12th, 2008, 06:09 PM
I have this code, which I am trying to use to generate truth tables for boolean functions (I have written the code for these, boolean.h).
I need to be able to "dynamically" call a function, when the function name is in a variable (the argument to generate_table(), char** function). In python I could do it like:
exec "%s(1, 0)" % function
But I cant find out how to do it in C.
#include <stdio.h>
#include "boolean.h"
struct table
{
char** title;
int xy;
int xo;
int oy;
int oo;
};
int
print_table (struct table t)
{
printf("%s\n", t.title);
printf("X Y - Out\n");
printf("0 0 - %i\n", t.oo);
printf("0 1 - %i\n", t.oy);
printf("1 0 - %i\n", t.xo);
printf("1 1 - %i\n", t.xy);
return 0;
}
void
generate_table (char** function)
{
struct table t;
t.title = function;
t.xy = 1;
t.xo = 0;
t.oy = 0;
t.oo = 0;
print_table(t);
}
int
main ()
{
generate_table("NOT");
}
slavik
September 12th, 2008, 06:13 PM
I have this code, which I am trying to use to generate truth tables for boolean functions (I have written the code for these, boolean.h).
I need to be able to "dynamically" call a function, when the function name is in a variable (the argument to generate_table(), char** function). In python I could do it like:
exec "%s(1, 0)" % function
But I cant find out how to do it in C.
#include <stdio.h>
#include "boolean.h"
struct table
{
char** title;
int xy;
int xo;
int oy;
int oo;
};
int
print_table (struct table t)
{
printf("%s\n", t.title);
printf("X Y - Out\n");
printf("0 0 - %i\n", t.oo);
printf("0 1 - %i\n", t.oy);
printf("1 0 - %i\n", t.xo);
printf("1 1 - %i\n", t.xy);
return 0;
}
void
generate_table (char** function)
{
struct table t;
t.title = function;
t.xy = 1;
t.xo = 0;
t.oy = 0;
t.oo = 0;
print_table(t);
}
int
main ()
{
generate_table("NOT");
}
I have never seen this done ... in C
rnodal
September 12th, 2008, 06:26 PM
Have you considered using function pointers and naming the pointers NOT, OR etc?
-r
bobbocanfly
September 12th, 2008, 06:27 PM
Have you considered using function pointers and naming the pointers NOT, OR etc?
-r
I have had that suggested, but I am just new to C, so not sure where to start with that. DO you know where I could find examples? (My google-fu sucks :()
issih
September 12th, 2008, 06:34 PM
Not quite what you need, but it might be feasible with function pointers and a call table:
http://www.newty.de/fpt/intro.html#what
Hope that helps
rnodal
September 12th, 2008, 06:36 PM
If you want sample tutorials on function pointers then a Google search on "C Function Pointers" would give you a lot. If you don't want to deal with function pointers then have you considered going a different way? For example if the user call your function like this:
yourFunction("NOT");
Store the NOT string in your struct then in the function that takes the struct as a parameter call the appropriate function based on what the string is equal to.
-r
mike_g
September 12th, 2008, 06:43 PM
Funnily enough I was working on something similare yesterday, although I dident need to call the functions by string names. This makes things a little more complex, but I came up with an example.
I basically did it by creating a stuct that maps a string to a function pointer. For your prog you would need to make an extra function that accepts a string then calls the mapped function.
heres an example:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int and_gate(int a, int b) { return a&b; }
int or_gate(int a, int b) { return a|b; }
int not_gate(int a, int b) { return (a)?0:1; }
int xor_gate(int a, int b) { return a^b; }
int nor_gate(int a, int b) { return !(a|b); }
int nand_gate(int a, int b){ return !(a&b); }
typedef struct
{
int (*func)(int, int);
char name[6];
}Map;
Map* map_function(char* name, int(*func)(int, int) )
{
if(strlen(name) > 5) return NULL;
Map* new_map = (Map*)malloc(sizeof(Map));
strcpy(new_map->name, name);
new_map->func = func;
return new_map;
}
int main()
{
Map* map[6];
map[0] = map_function("And", and_gate);
map[1] = map_function("Or", or_gate);
map[2] = map_function("Not", not_gate);
map[3] = map_function("Xor", xor_gate);
map[4] = map_function("Nor", nor_gate);
map[5] = map_function("Nand",nand_gate);
int i;
for(i=0; i<6; i++)
printf("Function name %s mapped to address %p result of function(1, 0) is: %d\n",
map[i]->name, map[i]->func, map[i]->func(1, 0));
for(i=0; i<6; i++)
free(map[i]);
getchar(); getchar();
return 0;
}
If theres anything you find unclear about the code i'll try and explain it for you.
rnodal
September 12th, 2008, 06:49 PM
Are you sure it needs to be that complicated? Couldn't you just say:
pointer = &functionName;
-r
mike_g
September 12th, 2008, 06:51 PM
Yes, you could. And thats what I was doing, but from what I could tell of the original post the op wanted to use a string generated at runtime to identify the function name.
rnodal
September 12th, 2008, 06:59 PM
Yes, you could. And thats what I was doing, but from what I could tell of the original post the op wanted to use a string generated at runtime to identify the function name.
I see. I got you know. Thanks for taking the time to clarify.
-r
Yannick Le Saint kyncani
September 12th, 2008, 07:03 PM
Hi all, AFAIK, the only practical way to use a function by name in C is to use the dlopen()/dlsym() mechanism.
But in this case, it's like using an atomic bomb to kill a kitty (not that I kill kitties).
bobbocanfly
September 12th, 2008, 09:40 PM
Thanks for your help everyone! I used mike_g's idea and setup an array of structs with function pointers. I cycle through the array and strcmp the argument name and the name in the struct. Certainly much better than a huge if .. else if .. else mess.
Here is the code I have ended up with:
#include <stdio.h>
#include <string.h>
#include "boolean.h"
typedef struct
{
int (*func)(int, int);
char name[6];
} map;
struct table
{
char** title;
int xy;
int xo;
int oy;
int oo;
};
map* map_function(char* name, int(*func)(int, int) )
{
if(strlen(name) > 5) return NULL;
map* new_map = (map*)malloc(sizeof(map));
strcpy(new_map->name, name);
new_map->func = func;
return new_map;
}
int
print_table (struct table t)
{
printf("%s\n", t.title);
printf("X Y - Out\n");
printf("0 0 - %i\n", t.oo);
printf("0 1 - %i\n", t.oy);
printf("1 0 - %i\n", t.xo);
printf("1 1 - %i\n", t.xy);
return 0;
}
void
generate_table (char** function)
{
map* map[7];
map[0] = map_function("and", and);
map[1] = map_function("or", or);
map[2] = map_function("not", not);
map[3] = map_function("xor", xor);
map[4] = map_function("nor", nor);
map[5] = map_function("nand", nand);
map[6] = map_function("xnor", xnor);
struct table t;
t.title = function;
int i;
for (i = 0; i < 8; i++)
{
if (!strcmp(map[i]->name, t.title))
{
t.xy = map[i]->func(1, 1);
t.oo = map[i]->func(0, 0);
t.oy = map[i]->func(0, 1);
t.xo = map[i]->func(1, 0);
}
}
print_table(t);
}
mike_g
September 12th, 2008, 10:41 PM
Thanks for your help everyone! I used mike_g's idea and setup an array of structs with function pointers. I cycle through the array and strcmp the argument name and the name in the struct. Certainly much better than a huge if .. else if .. else mess.
While it is a novelty, for what you are using it for in your example I'd say you would be much better with a plain old if statement. For three reasons: less overhead, the code would be easier to read, and less lines of code; 71 compared to 48:
#include <stdio.h>
#include <string.h>
#include "boolean.h"
struct table
{
char** title;
int xy;
int xo;
int oy;
int oo;
};
int
print_table (struct table t)
{
printf("%s\n", t.title);
printf("X Y - Out\n");
printf("0 0 - %i\n", t.oo);
printf("0 1 - %i\n", t.oy);
printf("1 0 - %i\n", t.xo);
printf("1 1 - %i\n", t.xy);
return 0;
}
void
generate_table (char** function)
{
struct table t;
t.title = function;
if(!strcmp("and", t.title))
and(t);
else if (!strcmp("or", t.title))
or(t);
else if (!strcmp("not", t.title))
not(t);
else if (!strcmp("xor", t.title))
xor(t);
else if (!strcmp("nor", t.title))
nor(t);
else if (!strcmp("nand", t.title))
nand(t);
else if (!strcmp("xnor", t.title))
xnor(t);
print_table(t);
}
bobbocanfly
September 13th, 2008, 12:41 AM
While it is a novelty, for what you are using it for in your example I'd say you would be much better with a plain old if statement. For three reasons: less overhead, the code would be easier to read, and less lines of code; 71 compared to 48:
But where would the fun be in that?! :P
If I was writing this for a project, I probably would just go with the If statement, but I am trying to learn as much of C as I can and this way is a lot more fun.
redicon
April 7th, 2009, 06:00 PM
I've got the same problem but using variables.
Something like:
int var = 4;
And i want to print on screen 4 using a string with "var" inside.
My idea is to declare extern int var and use dlopen and dlsym to load it in runtime.
Can anyone help me to find a better solution?
CptPicard
April 7th, 2009, 06:57 PM
You can't resolve things dynamically by name in C. What you are trying to do seems to essentially call for the use of a hashtable...
Powered by vBulletin® Version 4.2.2 Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.