dlopen()
是一个C函数,用于在运行时动态加载共享库。该模式,如果你不熟悉,是这样的:std :: shared_ptr和dlopen(),避免未定义的行为
- 呼叫
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()
时,其调用析构函数 - 构建从
handle
一个std::shared_ptr<void> object
和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
做到这一点?
为什么你需要'std :: shared_ptr'给po poetter,由dlsym返回? – Slava
@Slava:保证一生(当有指针时不要调用'dlclose')。 – Jarod42
'std :: shared_ptr'的别名构造函数允许两个'std :: shared_ptr'在没有指向相同对象或甚至相同类型的情况下共享相同的“关闭条件”(我的术语,而非官方)。使用'std :: shared_ptr'作为'dlsym()'返回的值可以带来以下好处:库的生命周期与'object'的生命周期相关联。 – Arandur