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