dlopen()
एक सी फ़ंक्शन है जो रनटाइम पर साझा लाइब्रेरी को गतिशील रूप से लोड करने के लिए उपयोग किया जाता है। पैटर्न, मामले में आप परिचित नहीं हैं, इस प्रकार है:std :: shared_ptr और dlopen(), अपरिभाषित व्यवहार से बचने
- कॉल
dlopen("libpath", flag)
बात आप पुस्तकालय - Do से चाहते हैं के लिए एक
void *object
प्राप्त करने के लिए पुस्तकालय - कॉल
dlsym(handle, "object_name")
करने के लिए एकvoid *handle
पाने के लिए आपobject
- लाइब्रेरी को अनलोड करने के लिए
dlclose (handle)
पर कॉल करें।
यह सी ++, तथाकथित अलियासिंग निर्माता std::shared_ptr
की के लिए एक आदर्श यूज-केस में, है। पैटर्न हो जाता है:
- का निर्माण
dlopen("libpath", flag)
से एकstd::shared_ptr<void> handle
किdlclose()
फोन करेगा जब उसके नाशक कहा जाता है handle
से एकstd::shared_ptr<void> object
औरdlsym(handle, "object_name")
- का निर्माण अब हम
object
पारित कर सकते हैं जहाँ भी हम चाहते हैं, और पूरी तरह से के बारे में भूलhandle
; जबobject
के नाशक कहा जाता है, जब भी उस होता है,dlclose()
स्वतः
शानदार पैटर्न के नाम से जाना जाएगा, और यह खूबसूरती से काम करता है। हालांकि, एक छोटी सी समस्या है। उपरोक्त पैटर्न को void*
से whatever_type_object_is*
तक कास्ट की आवश्यकता है। यदि "object_name"
किसी फ़ंक्शन को संदर्भित करता है (जो उपयोग-मामले पर विचार करते समय अधिकांश समय करता है), यह अनिर्धारित व्यवहार है।
सी में, इसके आसपास जाने के लिए एक हैक है।
// ...
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");
// ...
जो स्पष्ट रूप से बस ठीक काम करता है, सी में लेकिन वहाँ एक आसान तरीका std::shared_ptr
के साथ ऐसा करना है: dlopen
आदमी पृष्ठ से?
आपको dlsym द्वारा लौटाए गए पॉइंटर में 'std :: shared_ptr' क्यों चाहिए? – Slava
@ स्लावा: जीवनकाल की गारंटी के लिए (उस पॉइंटर होने पर 'dlclose' को कॉल न करें)। – Jarod42
'std :: shared_ptr' का एलियासिंग कन्स्ट्रक्टर दो' std :: shared_ptr' को एक ही ऑब्जेक्ट या यहां तक कि उसी प्रकार की ओर इशारा किए बिना एक ही "करीबी स्थिति" (मेरा शब्द, आधिकारिक नहीं) साझा करने की अनुमति देता है। 'Dlsym()' द्वारा दिए गए मान के लिए 'std :: shared_ptr' का उपयोग करके मुझे यह लाभ प्राप्त होता है: लाइब्रेरी का जीवनकाल 'ऑब्जेक्ट' के जीवनकाल से जुड़ा हुआ है। – Arandur