I'm looking for a way to automatically (as part of the compilation/build process) generate a "table" of function pointers in C.
Specifically, I want to generate an array of structures something like:
typedef struct {
void (*p_func)(void);
char * funcName;
} funcRecord;
/* Automatically generate the lines below: */
extern void func1(void);
extern void func2(void);
/* ... */
funcRecord funcTable[] =
{
{ .p_func = &func1, .funcName = "func1" },
{ .p_func = &func2, .funcName = "func2" }
/* ... */
};
/* End automatically-generated code. */
...where func1 and func2 are defined in other source files.
So, given a set of source files, each of which which contain a single function that takes no arguments and returns void, how would one automatically (as part of the build process) generate an array like the one above that contains each of the functions from the files? I'd like to be able to add new files and have them automatically inserted into the table when I re-compile.
I realize that this probably isn't achievable using the C language or preprocessor alone, so consider any common *nix-style tools fair game (e.g. make, perl, shell scripts (if you have to)).
You're probably wondering why anyone would want to do this. I'm creating a small test framework for a library of common mathematical routines. Under this framework, there will be many small "test cases," each of which has only a few lines of code that will exercise each math function. I'd like each test case to live in its own source file as a short function. All of the test cases will get built into a single executable, and the test case(s) to be run can be specified on the command line when invoking the executable. The main() function will search through the table and, if it finds a match, jump to the test case function.
Automating the process of building up the "catalog" of test cases ensures that test cases don't get left out (for instance, because someone forgets to add it to the table) and makes it very simple for maintainers to add new test cases in the future (just create a new source file in the correct directory, for instance).
Hopefully someone out there has done something like this before. Thanks, StackOverflow community!
How about making a macro list as
#define FUNC_LIST \
FUNC( func1 ) \
FUNC( func2 ) \
FUNC( func3 ) \
FUNC( func4 ) \
FUNC( func5 )
and then expand the extern
definitions as
#define FUNC( _name ) extern void _name(void);
FUNC_LIST
#undef FUNC
and then expand the table as
#define FUNC( _name ) { .p_func = &_name, .funcName = #_name },
funcRecord funcTable[] = {
FUNC_LIST
};
#undef FUNC
If you have a strict naming convention for you test functions another suggestion is to look into using the function dlsym
with the handle set to RTLD_DEFAULT
and write a function that tries to look upp all functions at startup.
Example
#include <stdio.h>
#include <dlfcn.h>
void test2() {
printf("Second place is the first loser!\n");
}
void test42() {
printf("Read The Hitchhikers Guide To The Galaxy!\n");
}
int main() {
int i;
for (i=1; i<100; i++) {
char fname[32];
void (*func)();
sprintf(fname, "test%d", i);
func = dlsym(RTLD_DEFAULT, fname);
if (func)
func();
}
return 0;
}
If you are using MSVC, you can use
dumpbin /symbols foo.obj > foo_symbols.txt
To get all of the symbol names (not just functions) into a text file. Then parse the resulting file to extract the function names. Functions will be External
symbols in a section that is not UNDEF
Alternatively, you could link your objects into a temporary exe or dll and then look at the .MAP file produced by the linker to get the function names.
Or you could write your own code to parse the .obj files, they are in a modified COFF format and it's not that difficult to locate the symbol table and decode it. I did a partial decode of the COFF format once to get at the symbol table and it took a couple of days to write the code. http://en.wikipedia.org/wiki/COFF
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With