#7321 - Burre - Sun Jun 15, 2003 12:32 am
Hi all.
Does anyone know a way to call a function only using a function adress(&function)? I don't need any input values nor any return values (void function(void)). If you don't know how to do it in C/C++ a inline ASM example would do, but i would prefer C if possible.
I've tried to search amongst the standard C libs but without any luck.
Any help on the subject is highly appreciated! :)
_________________
"The best optimizer is between your ears..."
#7327 - col - Sun Jun 15, 2003 3:27 am
here's one way:
Code: |
void (*funcPtr) (); //declares funcPtr as a ptr to void func()
funcPtr = myFunction; //assign address to ptr
(*funcPtr)(); //call the function using the ptr
|
cheers
col
#7328 - sgeos - Sun Jun 15, 2003 4:00 am
col wrote: |
here's one way: *snip* |
I'll list another:
Code: |
void (*fptr)(void);
if (confirm)
fptr = delete;
else
fptr = confirm_delete;
fptr(); |
I realize that calling the function directly would work better.
-Brendan
#7363 - Burre - Mon Jun 16, 2003 1:14 pm
Thanks a lot!
When you think you know all you need to know about C something entirely new pops right up. ;)
I never could have guessed that one could declare pointers like that.
Some questions:
1. Is it safe to change the function adress on the fly while running the program?
2. If I sometime later wants to have input/return values in the function I only put them in the declaration, right?
3. Does return values function the same way as before? (int (*funcPtr)();)
4. What is the "confirm" test used for?
Anyway, thanks again for the help.
_________________
"The best optimizer is between your ears..."
#7374 - niltsair - Mon Jun 16, 2003 2:53 pm
>1. Is it safe to change the function adress on the fly while running the program?
Yes
>2. If I sometime later wants to have input/return values in the function I only put them in the declaration, right?
Yes
>3. Does return values function the same way as before? (int (*funcPtr)();)
Yes. The function pointer must be declared the same a the prototype of the function (return type, parameters). Not quite certain what happen else, the compiler most probably throw an error.
>4. What is the "confirm" test used for?
Just an example to show how a function can be dynamicly assigned to a function pointer, to be called afterward. So confirm was an abitrary condition to chose which function should be called.
#7375 - col - Mon Jun 16, 2003 3:07 pm
Burre wrote: |
1. Is it safe to change the function adress on the fly while running the program?
|
thats where the fun starts - thats what sgeos example does...
you can even roll your own polymorphism with function pointers, if you want a challenge ;)
Quote: |
3. Does return values function the same way as before? (int (*funcPtr)();)
|
the functionality is the same as for a 'normal' function call.
to declare a pointer to a function that takes a u8 and a u16 and returns an s32:
u32(*funcPtr)(u8, u16);
this can only refer to a function with the same signature - although you can probably cast it - never tried that...
Quote: |
Anyway, thanks again for the help. |
no problem
For a good explanation of the details of function pointers, how to read them! and what you can do with them, have a look at 'thinking in c++' by Bruce Eckel - the whole book is available as a free download from his website - great stuff :)
http://www.bruceeckel.com/
cheers
Col
#7397 - sgeos - Tue Jun 17, 2003 1:45 am
Burre wrote: |
1. Is it safe to change the function adress on the fly while running the program?
2. If I sometime later wants to have input/return values in the function I only put them in the declaration, right? |
Your function pointer only works with the 'right' kind of functions.
void (*fptr)(int, int);
Every single function needs this format, no retrun value and two integer inputs. You can set it to the address of any function, but I image that bad things will happen when you try to call it. For arbitrary input use something like this:
void (*fptr)(void *);
Then you can pass it a pointer to anything, probably a structure. If you want it to return a pointer to function (or accept one) use a void pointer instead.
void *(*fptr)(void);
Some neat things to do with this: you can create character spell lists, etc, that are completely composed of function pointers:
Code: |
void (*spell_list[16])(void *) =
{
healing, big_healing, clearance, crazy_magic,
fire, ice, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL
}; |
You can also tag functions onto items:
Code: |
struct item item[10] =
{
{"", 0, 0, 0, 0, 0, 0, NULL, NULL},
{"Potion", ITM | BRK, 0, 0, 0, 0, 0, b_potion, g_potion},
{"Winter Wand", WEP, 0, 50, 5, 60, 0, frost, NULL},
}; |
There is a function pointer for in battle and out of battle above. There are many other very useful things you can do with pointers to functions. Have fun with it, pointers to functions are good stuff!
-Brendan
#7516 - Burre - Thu Jun 19, 2003 1:05 am
Yeah I figured it worked that way. Right now I only use it for directing IRQ to its proper IRQ function in my IRQ handler, but I'll surely dig some more in the possibilities if I feel the need or the opportunity.
_________________
"The best optimizer is between your ears..."