dlopen()
to funkcja języka C używana do dynamicznego ładowania bibliotek współdzielonych w środowisku wykonawczym. Wzór, w przypadku gdy nie jesteś zaznajomiony jest tak:std :: shared_ptr i dlopen(), unikając niezdefiniowanych zachowań
- połączeń
dlopen("libpath", flag)
dostaćvoid *handle
do biblioteki - połączeń
dlsym(handle, "object_name")
dostaćvoid *object
z rzeczą, którą chcesz z biblioteki - Do czego chcesz, aby
object
- wyładować biblioteki.
To jest w C++, doskonałej użytkowej przypadku do tzw aliasing konstruktora z std::shared_ptr
. Wzór przyjmuje postać:
- Construct
std::shared_ptr<void> handle
oddlopen("libpath", flag)
że wezwiedlclose()
gdy jego destruktora nazywa - Narysuj
std::shared_ptr<void> object
zhandle
idlsym(handle, "object_name")
- Teraz możemy przejść
object
gdziekolwiek chcemy i całkowicie zapomnieć ohandle
; gdy destruktorobject
„s nazywa, ilekroć że zdarza się,dlclose()
zostanie wywołany automagicznie
Brilliant wzór i działa pięknie. Ale mały problem. Powyższy wzór wymaga obsady od void*
do whatever_type_object_is*
. Jeśli "object_name"
odnosi się do funkcji (która w większości przypadków robi to, biorąc pod uwagę przypadek użycia), jest to niezdefiniowane zachowanie.
W języku C jest hack do obejścia tego. Od strony dlopen
Man:
// ...
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");
// ...
co oczywiście działa dobrze, w C. Ale czy istnieje prosty sposób to zrobić z std::shared_ptr
?
dlaczego potrzebujesz 'std :: shared_ptr' do poointer, zwrócony przez dlsym? – Slava
@Slava: aby zagwarantować całe życie (nie wywołuj 'dlclose' gdy jest tam ten wskaźnik). – Jarod42
Konstruktor aliasów 'std :: shared_ptr' umożliwia dwóm' std :: shared_ptr's współdzielenie tego samego "warunku zamknięcia" (mój termin, nie oficjalny) bez wskazania tego samego obiektu lub nawet tego samego typu. Użycie 'std :: shared_ptr' dla wartości zwróconej przez' dlsym() 'zyskuje mi tę korzyść: okres istnienia biblioteki jest związany z czasem życia obiektu. – Arandur