Я пишу интерфейсный слой в разделяемую библиотеку, которую мы открываем через dlopen / dlsym. Параметры функций могут изменяться в зависимости от того, скомпилирована ли библиотека для системы A против системы B.
У меня была мысль, что вместо того, чтобы делать кучу typedefs, я мог бы попытаться создать массив всех указатели на функции возвращаются из dlsym и затем в конечном итоге используют VA_ARGS для передачи данных. Это также позволило бы мне иметь дело с расширяемостью - если параметры библиотеки изменятся, нам просто нужно будет обновить вызывающие функции, вместо приведенных ниже typedefs. По сути, я хочу изменить что-то вроде этого:
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();
}
на это:
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]();
}
Возможно ли это? Я знаю, что массив пустот незаконен. Я не могу использовать uintptr_t вместо него, так как они предназначены для указателей на данные (а не функции). Есть ли другие варианты, кроме создания больших # define для каждой конфигурации и выполнения оригинального способа?