dlsym()和dlopen()在C ++中的替代方法 [英] Alternatives to dlsym() and dlopen() in C++
问题描述
我有一个应用程序的一部分使用共享库。这些库在编译时链接。
在运行时,加载器期望共享对象在 LD_LIBRARY_PATH
中,如果没有找到,整个应用程序崩溃,出现错误无法加载共享库。注意,不能保证客户端将有库,在这种情况下,我想让应用程序留下合适的错误消息,独立部分应该正常工作。
I have an application a part of which uses shared libraries. These libraries are linked at compile time.
At Runtime the loader expects the shared object to be in the LD_LIBRARY_PATH
, if not found the entire application crashes with error "unable to load shared libraries".Note that there is no guarantee that client would be having the library, in that case I want the application to leave a suitable error message also the independent part should work correctly.
为此,我使用 dlsym()
和 dlopen()
共享库。问题是如果我有很多的API,我必须使用 dlsym()
和ptrs访问它们在我的情况下,导致内存损坏
For this purpose I am using dlsym()
and dlopen()
to use the API in the shared library. The problem with this is if I have a lot of functions in the API, i have to access them Individually using dlsym()
and ptrs which in my case are leading to memory corruption and code crashes.
有任何替代方案吗?
推荐答案
你的问题的常见解决方案是声明一个函数指针表,做一个单一的dlsym()来找到它,然后通过指向该表的指针调用所有其他函数。示例(未测试):
The common solution to your problem is to declare a table of function pointers, to do a single dlsym() to find it, and then call all the other functions through a pointer to that table. Example (untested):
// 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
使用dlsym和指针单独访问您的API函数本身不会导致内存损坏和崩溃。很可能你只是有错误。
P.S. Accessing your API functions individually using dlsym and pointers does not in itself lead to memory corruption and crashes. Most likely you just have bugs.
编辑:
你可以使用这个完全相同的技术与第三方库。创建 libdrmaa_wrapper.so
并将 api_table
添加到其中。将包装器直接链接到 libdrmaa.so
。
You can use this exact same technique with a 3rd-party library. Create a libdrmaa_wrapper.so
and put the api_table
into it. Link the wrapper directly against libdrmaa.so
.
在主可执行文件中, dlopen libdrmaa_wrapper.so,RTLD_NOW)
。如果(而且只有) libdrmaa.so
在运行时出现,并且提供您使用的所有API函数,此 dlopen
在 api_table
中。如果它成功,单个 dlsym
调用将允许您访问整个API。
In the main executable, dlopen("libdrmaa_wrapper.so", RTLD_NOW)
. This dlopen
will succeed if (and only if) libdrmaa.so
is present at runtime and provides all API functions you used in the api_table
. If it does succeed, a single dlsym
call will give you access to the entire API.
这篇关于dlsym()和dlopen()在C ++中的替代方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!