sud*_*03r 18 c++ shared-libraries dynamic-loading dlsym
我有一个应用程序,其中一部分使用共享库.这些库在编译时链接.
在运行时,加载器期望共享对象在LD_LIBRARY_PATH
,如果没有找到整个应用程序崩溃,错误"无法加载共享库".注意,不能保证客户端将拥有库,在这种情况下我想要应用程序留下合适的错误消息,独立部分也应该正常工作.
为此,我使用dlsym()
并dlopen()
在共享库中使用API.这个问题是如果我在API中有很多功能,我必须单独使用dlsym()
和ptrs 访问它们,在我的情况下会导致内存损坏和代码崩溃.
这有什么替代方案吗?
Emp*_*ian 32
你的问题的常见解决方案是声明一个函数指针表,做一个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
Run Code Online (Sandbox Code Playgroud)
PS使用dlsym和指针单独访问API函数本身并不会导致内存损坏和崩溃.很可能你只是有虫子.
编辑:
您可以使用与第三方库完全相同的技术.创建一个libdrmaa_wrapper.so
并放入api_table
其中.直接链接包装器libdrmaa.so
.
在主可执行文件中dlopen("libdrmaa_wrapper.so", RTLD_NOW)
.dlopen
如果(并且仅当)libdrmaa.so
在运行时出现并且提供您在中使用的所有API函数,这将成功api_table
.如果成功,单个dlsym
调用将允许您访问整个API.