I'm writing an interface layer to a shared library we are opening via dlopen/dlsym. The parameters to the functions may change depending on whether the library is compiled for system A vs system B.
I had a thought that instead of doing a bunch of typedefs, I could try to create an array of all of the function pointers returned from dlsym and then eventually use VA_ARGS to pass in the data. This would also allow me to deal with extensibility-- if the library parameters change, we'd just need to update the calling functions, instead of the typedefs below, too. Basically, I'm looking to change something like this:
typedef int* (*foo_t)(int, int);
typedef int* (*bar_t)(int, int, char*, int);
typedef void (*baz_t)(void);
void GetStuff()
{
void *handle = dlopen("/my/cool/libLibrary.so", RTLD_LAZY);
foo_t foo = dlsym(handle, "TheFooFunction");
bar_t bar = dlsym(handle, "TheBarFunction");
baz_t baz = dlsym(handle, "TheBazFunction");
foo(1, 2);
bar(3, 4, "cool", 5);
baz();
}
into this:
enum funcs
{
FUNC_FOO = 0,
FUNC_BAR = 1,
FUNC_BAZ = 2,
FUNC_MAX
};
void funcArray[FUNC_MAX]; // Not legal - looking for a way to do something like this...
char *functionNames[FUNC_MAX] =
{
[FUNC_FOO] = "TheFooFunction",
[FUNC_BAR] = "TheBarFunction",
[FUNC_BAZ] = "TheBazFunction"
};
void GetStuff()
{
void *handle = dlopen("/my/cool/libLibrary.so", RTLD_LAZY);
for (int i = 0; i < FUNC_MAX; i++)
{
funcArray[i] = dlsym(handle, functionNames[i]);
}
funcArray[FUNC_FOO](1, 2);
funcArray[FUNC_BAR](3, 4, "cool", 5);
funcArray[FUNC_BAZ]();
}
Is this possible? I know the array of voids is illegal. I can't use uintptr_t in it's place, since those are for data (not function) pointers. Are there any other options other than creating big #define's for each configuration and doing it the original way?