Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!rutgers!bellcore!faline!thumper!ulysses!mhuxo!mhuxu!m10ux!mnc From: mnc@m10ux.UUCP (Michael Condict) Newsgroups: comp.lang.c Subject: Re: Functions pointers and stuff Message-ID: <906@m10ux.UUCP> Date: 31 Mar 89 04:39:34 GMT References: <1715@leah.Albany.Edu> <3182@goofy.megatest.UUCP> Organization: AT&T Bell Labs, Murray Hill Lines: 65 In article <3182@goofy.megatest.UUCP>, djones@megatest.UUCP (Dave Jones) writes: > From article <1715@leah.Albany.Edu>, by rds95@leah.Albany.Edu (Robert Seals): > > Is there some sneaky way to execute the function when all I know is > > the name of it, i.e., a pointer to several letters which spell it's name. > > > > There's no portable way. What system are you running? What version > of C? While all the caveats mentioned in previous articles apply, here is a version that is portable between System V and BSD derived UNIX's, including Suns. Note the occurrences of exit(n) for each of the many different things that can go wrong. Also note that it makes no attempt to solve the problem of converting argv[0] into an accessible file name. It calls the function "Funky" by using nm to look up the address of the function in the a.out file. Unfortunately, this requires one #ifdef BSD, which you should #define when compiling on Berkeley-derived systems. The reason is that the BSD nm command prints hex address, while System V prints decimal. ---------------------------------------------------------------------------- #include #include void Funky (str) char *str; { printf("Funky: %s\n", str); } main(argc, argv) int argc; char **argv; { char *cp, *fname = "Funky"; static char addr_str[100], nm_cmd[200]; long addr = 0; FILE *f; void (*func_p)(); printf("Begin test.\n"); if (!argv[0] || ! argv[0][0]) exit(1); /* A command that will print the function address in ASCII: */ (void)sprintf(nm_cmd, "nm %s | egrep '(^|[^a-zA-Z_])_%s[^a-zA-Z_0-9]'", argv[0], fname); if ((f = popen(nm_cmd, "r")) == NULL) exit(2); if (!fgets(addr_str, 99, f)) exit(3); if (!addr_str[0]) exit(4); /* Find the address in the nm output line: */ for (cp = addr_str; *cp && !isdigit(*cp); cp++) ; if (!isdigit(*cp)) exit(5); #ifdef BSD /* Convert ASCII hex representation to binary: */ (void)sscanf(cp, "%x", &addr); #else addr = atoi(cp); #endif if (!addr) exit(6); func_p = (void (*)())addr; printf("func_p = 0x%x = %d\n", func_p, func_p); (*func_p)("was called."); printf("End Test.\n"); exit(0); } -- Michael Condict {att|allegra}!m10ux!mnc AT&T Bell Labs (201)582-5911 MH 3B-416 Murray Hill, NJ