dlopen()
是C函数,用于在运行时动态加载共享库。因此,如果您不熟悉该模式,则为:
dlopen("libpath", flag)
以将void *handle
获取到库dlsym(handle, "object_name")
以从库void *object
。object
做你想做的事dlclose (handle)
卸载库。 在C++中,这是所谓的
std::shared_ptr
别名构造函数的理想用例。该模式变为:std::shared_ptr<void> handle
构造一个dlopen("libpath", flag)
,当其析构函数称为dlclose()
std::shared_ptr<void> object
和handle
构造dlsym(handle, "object_name")
object
,而完全不必考虑handle
了;当object
的析构函数被调用时,只要碰巧被调用,dlclose()
就会被自动调用绚丽的图案,效果很好。不过,这是一个小问题。上面的模式需要从
void*
转换为whatever_type_object_is*
。如果"object_name"
引用了一个函数(考虑到用例,大多数情况下是这样),则这是未定义的行为。在C语言中,有一种解决方法。从
dlopen
手册页:// ...
void *handle;
double (*cosine)(double);
// ...
handle = dlopen("libm.so", RTLD_LAZY);
// ...
/* Writing: cosine = double (*)(double)) dlsym(handle, "cos");
would seem more natural, but the C99 standard leaves
casting from "void *" to a function pointer undefined.
The assignment used below is the POSIX.1-2003 (Technical
Corrigendum 1) workaround; see the Rationale for the
POSIX specification of dlsym(). */
*(void **) (&cosine) = dlsym(handle, "cos");
// ...
显然在C中可以正常工作。但是有没有一种简单的方法可以使用
std::shared_ptr
做到这一点呢? 最佳答案
嗯,这并不是完全正确的,至少在C++中,它只是有条件支持的。
5.2.10.8 说:
因此,假设dlsym
在内部执行的操作是将函数指针转换为void*
,那么我相信,只要将其转换回函数指针即可。
关于c++11 - std::shared_ptr和dlopen(),避免未定义的行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36040814/