jantypas@ucrmath.UUCP (John Antypas) (09/15/88)
This may seem like a simple question but I've no luck with an answer so
perhaps the net could help.
In a graphics application we're writing at work, we have several functions for
drawing lines, circles etc. We'd like to set up something like a vector table.
If the vector table has a NULL in a spot, then the interpreter will use its
internal routines instead of faster device specific code. As an example:
vectors[] = { dev_line(),
dev_box(),
dev_circle(),
dev_arc(),
dev_text()
}
This says we have device specific code for all five functions. Yet when I
try to copy function addresses, the compiler complains. How do I get the
address of a funciton and put it into an array for calling later?
Thanks.
John Antypas -- Soft21 --21st Century Software:
UUCP: {crash, garp, killer, pyramid, reed, ucsd!ucrmath}!soft21!jantypas
Internet: jantypas%soft21.uucp@{garp.MIT.EDU, ucsd.EDU}
Domains: jantypas@{soft21.Riverside.CA.US, soft21.CTS.COM}
steve@oakhill.UUCP (steve) (09/16/88)
I'm sorry for clogging the newsgroup with this reply, but my Email keeps bouncing back. In article <414@ucrmath.UUCP>, jantypas@ucrmath.UUCP (John Antypas) writes: > This may seem like a simple question but I've no luck with an answer so > perhaps the net could help. > > In a graphics application we're writing at work, we have several functions for > drawing lines, circles etc. We'd like to set up something like a vector table. > If the vector table has a NULL in a spot, then the interpreter will use its > internal routines instead of faster device specific code. As an example: > > vectors[] = { dev_line(), > dev_box(), > dev_circle(), > dev_arc(), > dev_text() > } > > This says we have device specific code for all five functions. Yet when I > try to copy function addresses, the compiler complains. How do I get the > address of a funciton and put it into an array for calling later? > > Thanks. > > John Antypas -- Soft21 --21st Century Software: > UUCP: {crash, garp, killer, pyramid, reed, ucsd!ucrmath}!soft21!jantypas > Internet: jantypas%soft21.uucp@{garp.MIT.EDU, ucsd.EDU} > Domains: jantypas@{soft21.Riverside.CA.US, soft21.CTS.COM} I have some function array code I took from another source a while back. It works and it shows some of the ways and uses this sort of thing is usefull for. Please feel free to use any part of it. Of course I've simplified it for you. --------------------------START OF CODE------------------------------ #define COMMAND_LIST 1 #define COMMAND_ADD 2 #define COMMAND_QUIT 3 #define COMMAND_HELP 4 #define COMMAND_SHOW 5 char buffer[150]; char *buffer_place; struct command_info { char *name; short significant; int number; void (*function)(); }; void command_add(),command_help(),command_list(),command_show(); struct command_info command_table[] = { { "add", 1, COMMAND_ADD, command_add }, { "help", 1, COMMAND_HELP, command_help }, { "list", 1, COMMAND_LIST, command_list }, { "quit", 1, COMMAND_QUIT, NULL }, { "show", 1, COMMAND_SHOW, command_show }, { NULL, 0, 0, NULL }}; void run_commands() { boolean more; struct command_info *this_command; int linelength; more = YES; while (more) { printf("Command : "); linelength = readline(stdin,YES); if (linelength) { this_command = get_command(command_table); if (this_command->function) (*this_command->function)(); else if (this_command->number == COMMAND_QUIT) more = NO; else { printf("Unknown or ambiguious command not understood.\n"); printf("Type Help for help\n"); } } } return; } struct command_info *get_command(command_table) struct command_info *command_table; { struct command_info *this_command; int count; char *this_c; boolean more; boolean somemore; boolean good; this_command = command_table; more = YES; while (this_command->name && more) { count = 0; this_c = this_command->name; buffer_place = buffer; good = YES; somemore = YES; while (good && somemore) { if (*this_c && *buffer_place && *buffer_place != ' ') { if (*this_c == *buffer_place) { count++; this_c++; buffer_place++; } else good = NO; } else if (*buffer_place && *buffer_place != ' ') good = NO; else somemore = NO; } if (count >= this_command->significant && good) more = NO; else this_command++; } return(this_command); } -----------------------------END OF CODE------------------------------ enough from this mooncalf - Steven ---------------------------------------------------------------------------- These opinions aren't necessarily Motorola's or Remora's - but I'd like to think we share some common views. ---------------------------------------------------------------------------- Steven R Weintraub cs.utexas.edu!oakhill!devsys!steve Motorola Inc. Austin, Texas (512) 440-3023 (office) (512) 453-6953 (home) ----------------------------------------------------------------------------
gwyn@smoke.ARPA (Doug Gwyn ) (09/16/88)
In article <414@ucrmath.UUCP> jantypas@ucrmath.UUCP (John Antypas) writes: >try to copy function addresses, the compiler complains. How do I get the >address of a funciton and put it into an array for calling later? Just use the name of the (previously declared) function; that IS a pointer to the function. Note that all the function pointers in your array should have the same type, which means that all the functions themselves should have the same type. (Also of course the array needs to be declared as an array of pointers to functions having that type.)
nate@altos86.UUCP (Nathaniel Ingersoll) (09/21/88)
In article <414@ucrmath.UUCP> jantypas@ucrmath.UUCP (John Antypas) writes: >drawing lines, circles etc. We'd like to set up something like a vector table. >If the vector table has a NULL in a spot, then the interpreter will use its >internal routines instead of faster device specific code. As an example: > >vectors[] = { dev_line(), > dev_box(), > dev_circle(), > dev_arc(), > dev_text() > } > >Thanks. > >John Antypas -- Soft21 --21st Century Software: I often have programs where I look up a function based on something like user input, and what I usually do is similar to: /* hjkl character movement ... */ int f_left(), f_right(), f_up(), f_down(); int (*vectors[0200])(); init_vec() { vectors['h'] = f_left; vectors['j'] = f_down; vectors['k'] = f_up; vectors['l'] = f_right; } or, similarly, #define CASE1 0 #define CASE2 1 ... #define CASEN N /* some N */ where some input function returns a CASEx, and then you can have an array of function pointers like int (*vectors[how many])() = { f_case1, f_case2, ... }; and go like int whatcase, getcase(); int (*f)(), invalidcase(); whatcase = getcase(); if (whatcase >= 0 && whatcase < MAXCASE) f = vectors[whatcase]; else f = invalidcase; (*f)(...); Now that I've beaten this to death, good luck. -- Nathaniel Ingersoll Altos Computer Systems, SJ CA ...!ucbvax!sun!altos86!nate altos86!nate@sun.com
english@panarea.usc.edu (Joe English) (09/22/88)
In article <414@ucrmath.UUCP> jantypas@ucrmath.UUCP (John Antypas) writes: >We'd like to set up something like a vector table. >If the vector table has a NULL in a spot, then the interpreter will use its >internal routines instead of faster device specific code. As an example: > >vectors[] = { dev_line(), > dev_box(), > dev_circle(), > dev_arc(), > dev_text() > } > >[...] ... when I >try to copy function addresses, the compiler complains. How do I get the >address of a funciton and put it into an array for calling later? This works, (and it's an excellent way to set up a device driver, I might add.) The only problem with the initialization is that you're using function _call_ syntax, which can't be evaluated at compile time. If you declare the functions (int dev_line(), dev_box(),...;) beforehand, you can write: int (*vectors)()[] = { dev_line, dev_box, ... } _without_ parentheses; this evaluates to the address of the function, which can be initialized, instead of a function call. /|/| Joe English -----< | | ARPA: english%lipari@oberon.usc.edu O \|\|