कुछ अन्य उत्तरों के सुझावों के विपरीत, DllImport
विशेषता का उपयोग करना अभी भी सही दृष्टिकोण है।
मुझे ईमानदारी से समझ में नहीं आता कि आप दुनिया में हर किसी की तरह क्यों नहीं कर सकते हैं और अपने DLL के लिए एक रिश्तेदार रास्ता बता सकते हैं । हां, जिस पथ पर आपका एप्लिकेशन इंस्टॉल किया जाएगा वह अलग-अलग लोगों के कंप्यूटरों पर भिन्न होता है, लेकिन यह मूल रूप से एक सार्वभौमिक नियम है जब यह तैनाती की बात आती है। DllImport
तंत्र इसे ध्यान में रखकर बनाया गया है।
वास्तव में, यह भी नहीं है DllImport
कि इसे संभालता है। यह मूल Win32 DLL लोडिंग नियम है जो चीजों को नियंत्रित करता है, भले ही आप आसान प्रबंधित रैपर (P / Invoke marshaller सिर्फ कॉल LoadLibrary
) का उपयोग कर रहे हों । उन नियमों को यहां बड़े विस्तार से प्रस्तुत किया गया है , लेकिन महत्वपूर्ण यहां प्रस्तुत हैं:
सिस्टम DLL के लिए खोज करने से पहले, यह निम्नलिखित की जाँच करता है:
- यदि समान मॉड्यूल नाम वाला DLL पहले से ही मेमोरी में लोड है, तो सिस्टम लोड की गई DLL का उपयोग करता है, चाहे वह किसी भी निर्देशिका में हो। सिस्टम DLL के लिए खोज नहीं करता है।
- यदि DLL Windows के संस्करण के लिए ज्ञात DLL की सूची में है, जिस पर अनुप्रयोग चल रहा है, तो सिस्टम ज्ञात DLL की प्रतिलिपि का उपयोग करता है (और ज्ञात DLL के निर्भर DLL, यदि कोई हो)। सिस्टम DLL के लिए खोज नहीं करता है।
यदि SafeDllSearchMode
सक्षम (डिफ़ॉल्ट) है, तो खोज क्रम निम्नानुसार है:
- वह निर्देशिका जिससे एप्लिकेशन लोड की गई है।
- सिस्टम निर्देशिका। उपयोग
GetSystemDirectory
इस निर्देशिका का पथ प्राप्त करने के लिए फ़ंक्शन का ।
- 16-बिट सिस्टम निर्देशिका। ऐसा कोई फ़ंक्शन नहीं है जो इस निर्देशिका का पथ प्राप्त करता है, लेकिन इसे खोजा जाता है।
- विंडोज निर्देशिका। उपयोग
GetWindowsDirectory
इस निर्देशिका का पथ प्राप्त करने के लिए फ़ंक्शन का ।
- वर्तमान निर्देशिका।
- निर्देशिका जो
PATH
पर्यावरण चर में सूचीबद्ध हैं । ध्यान दें कि इसमें एप्लिकेशन पथ रजिस्ट्री कुंजी द्वारा निर्दिष्ट प्रति-एप्लिकेशन पथ शामिल नहीं है। DLL खोज पथ की गणना करते समय ऐप पथ कुंजी का उपयोग नहीं किया जाता है।
इसलिए, जब तक आप अपने DLL को सिस्टम DLL (जिसे आप स्पष्ट रूप से, कभी भी, किसी भी परिस्थिति में नहीं करना चाहिए) के रूप में एक ही चीज़ का नामकरण कर रहे हैं, तो डिफ़ॉल्ट खोज क्रम उस निर्देशिका में दिखना शुरू हो जाएगा जहाँ से आपका आवेदन लोड किया गया था। यदि आप इंस्टॉल के दौरान वहां डीएलएल रखते हैं, तो यह मिल जाएगा। यदि आप केवल सापेक्ष रास्तों का उपयोग करते हैं, तो सभी जटिल समस्याएं दूर हो जाती हैं।
बस लिखें:
[DllImport("MyAppDll.dll")] // relative path; just give the DLL's name
static extern bool MyGreatFunction(int myFirstParam, int mySecondParam);
लेकिन अगर यह किसी भी कारण से काम नहीं करता है , और आपको DLL के लिए एक अलग निर्देशिका में देखने के लिए एप्लिकेशन को मजबूर करने की आवश्यकता है, तो आप SetDllDirectory
फ़ंक्शन का उपयोग करके डिफ़ॉल्ट खोज पथ को संशोधित कर सकते हैं ।
ध्यान दें कि, प्रलेखन के अनुसार:
कॉल करने के बाद SetDllDirectory
, मानक DLL खोज पथ है:
- वह निर्देशिका जिससे एप्लिकेशन लोड की गई है।
lpPathName
पैरामीटर द्वारा निर्दिष्ट निर्देशिका ।
- सिस्टम निर्देशिका।
GetSystemDirectory
इस निर्देशिका का पथ प्राप्त करने के लिए फ़ंक्शन का उपयोग करें ।
- 16-बिट सिस्टम निर्देशिका। ऐसा कोई फ़ंक्शन नहीं है जो इस निर्देशिका का पथ प्राप्त करता है, लेकिन इसे खोजा जाता है।
- विंडोज निर्देशिका।
GetWindowsDirectory
इस निर्देशिका का पथ प्राप्त करने के लिए फ़ंक्शन का उपयोग करें ।
- निर्देशिका जो
PATH
पर्यावरण चर में सूचीबद्ध हैं ।
इसलिए जब तक आप इस फ़ंक्शन को पहली बार DLL से आयात किए गए फ़ंक्शन को कॉल करते हैं, तब तक आप DLL का पता लगाने के लिए उपयोग किए गए डिफ़ॉल्ट खोज पथ को संशोधित कर सकते हैं। बेशक, लाभ यह है कि आप इस फ़ंक्शन को एक गतिशील मान पास कर सकते हैं जो रन-टाइम पर गणना की जाती है। यह DllImport
विशेषता के साथ संभव नहीं है , इसलिए आप अभी भी एक रिश्तेदार पथ (केवल DLL का नाम) का उपयोग करेंगे, और आपके लिए इसे खोजने के लिए नए खोज क्रम पर भरोसा करेंगे।
आपको इस फ़ंक्शन को P / Invoke करना होगा। घोषणा इस तरह दिखती है:
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool SetDllDirectory(string lpPathName);