您的问题的常见解决方案是声明一个函数指针表,执行单个 dlsym() 来查找它,然后通过指向该表的指针调用所有其他函数。示例(未经测试):
// libfoo.h
struct APIs {
void (*api1)(void);
void *(*api2)(int);
long (*api3)(int, void *);
};
// libfoo.cc
void fn1(void) { ... }
void *fn2(int) { ... }
long fn3(int, void *) { ... }
APIs api_table = { fn1, fn2, fn3 };
// client.cc
#include "libfoo.h"
...
void *foo_handle = dlopen("libfoo.so", RTLD_LAZY);
if (!foo_handle) {
return false; // library not present
}
APIs *table = dlsym(foo_handle, "api_table");
table->api1(); // calls fn1
void *p = table->api2(42); // calls fn2
long x = table->api3(1, p); // calls fn3
PS 使用 dlsym 和指针单独访问您的 API 函数本身不会导致内存损坏和崩溃。很可能你只是有错误。
编辑:
您可以将这种完全相同的技术与第 3 方库一起使用。创建一个libdrmaa_wrapper.so
并将其api_table
放入其中。将包装器直接链接到libdrmaa.so
.
在主可执行文件中,dlopen("libdrmaa_wrapper.so", RTLD_NOW)
. 如果dlopen
(且仅当)libdrmaa.so
在运行时存在并提供您在api_table
. 如果确实成功,则只需一次dlsym
调用即可让您访问整个 API。