Penguin
Blame: CastingPointerToFunction
EditPageHistoryDiffInfoLikePages
Annotated edit history of CastingPointerToFunction version 13, including all changes. View license author blame.
Rev Author # Line
12 AristotlePagaltzis 1 [C] is probably the only language you can do this in (except maybe [Forth]). Other languages either have no way of doing this, or don't treat data and code differently.
10 JohnMcPherson 2 (Feel free to add examples for other languages here.)
3
4 Once you've got a pointer to your machine code (usually an array of bytes or ints), you need to cast it to the appropriate type and call it. Eg if you have a pointer to a function which takes a char *, you can call it like this:
5
6 ((int (*)(char *)) p)("hello, world");
7
8 The secret here is the parenthesis around the star. To declare a variable to hold the above, use this:
9
10 int (*func_t)(char *);
11
11 JohnMcPherson 12 In C (and [C++]), a function name is really just a pointer to a function, and you can think of () as an operator to make a call to that function. Using a typedef to hold the function type might make that clear:
13
14 typedef int (*func_t)(char *);
10 JohnMcPherson 15
16 int foo(char *x) {
17 printf("%s",x);
18 }
19
20
11 JohnMcPherson 21 func_t p = foo; /* assign function pointer to p */
22 return p("Narf!"); /* call that function, and return the result */
10 JohnMcPherson 23
24 -----
25
26 And you need to do this why?
27
28 * Jon was using it to "compile" something then jump to it in C, by casting an array as a function, then calling it.
29
30 * I use it frequently to do things like have a lookup table of name to function. For example in ircu, there is a function called "parse" which takes a line from a user, splits it up into a function and it's arguments, then scans through a table of functions and their names, when it finds one that matches that command, it calls the function with the arguments it parsed earlier. Nice 'n zippy.
31
32 * A library back-end may provide functionality that should behave differently for different front ends. For example, a library that wants to print out diagnostic messages uses a function pointer, and then a console app can pass a pointer to a function that prints out to the terminal (or stdout(3) or stderr(3)) while a graphical app can create a callback function that pops up a [GUI] window or something.
33
34 * Some functions take another function as an argument. Probably the most well-known example is qsort(3) the quick sort algorithm -- you need to pass it an array and a function for comparing array elements. Also see the example below.
35
36
37 from atexit(3):
38 #include <stdlib.h>
39 int atexit(void (*function)(void));
40
41 you can specify functions to be executed after main() finishes.
42 You do this by calling atexit(functionname), as a function name
43 without () is a pointer to that function. However, if you want to this for a function that returns something other than null, you have to type cast it. Eg:
44 (int endwin() is an ncurses function).
45
46 atexit(endwin);
47 source.cpp:227: passing `int (*)()' as argument 1 of `atexit(void (*)())'
48 atexit(void)endwin);
49 source.cpp:227: void value not ignored as it ought to be
50
51 The trick is to cast the pointer to a function pointer of the required type:
52 atexit( (void(*)())endwin );
53
54 ----
55 It is worth noticing that in languages where functions are first class objects (such as [LISP] and [Scheme]), passing around pointers to functions is entirely normal (and type safe); even in [Java] and [Python] [Introspection] allows type safe access to such functionality.

PHP Warning

lib/blame.php:177: Warning: Invalid argument supplied for foreach()