मैं क्या हासिल करना
मैं एक प्रोग्राम है जो गतिशील रूप से प्लग इन के रूप DLLs लोड करता है पर काम कर रहा हूँ कोशिश कर रहा हूँ की लंबी कहानी। मैं माइक्रोसॉफ्ट विजुअल सी ++ 2008 का उपयोग कर प्रोग्राम संकलित कर रहा हूं। फिर भी, मान लीजिए कि किसी भी दृश्य सी ++ संस्करण के साथ क्यूटी कार्यों का समर्थन किया जाना चाहिए। कार्यक्रम निर्देशिका लेआउट पीछा कर रहा है:सी ++: प्रकट होता है और अलग अलग निर्देशिका से DLLs गतिशील लोड हो रहा है
| plugins/
| plugin1.dll
| plugin2.dll
| QtCore4.dll
| QtGui4.dll
| program.exe
program.exe
पता चलता है सभी प्लग-इन DLL फ़ाइलों, उन पर प्रदर्शन करती है LoadLibrary() और एक निश्चित हस्ताक्षर फ़ंक्शन को कॉल जानने के लिए कि यह वास्तव में एक प्लगइन है या नहीं। यह उन कंप्यूटरों पर बहुत अच्छी तरह से काम करता है जिनके पास MSVC90 स्थापित vcredist है। स्वाभाविक रूप से, प्रोग्राम को सभी कंप्यूटरों पर काम करने के लिए मुझे इसे msvc * .dll फ़ाइलों और उपयुक्त मैनिफेस्ट फ़ाइल के साथ पुनर्वितरित करना होगा। क्यूटी डीएलएल को चलाने के लिए रेडिस्ट की भी आवश्यकता होती है।
अब, मैंने चयनित रेडिस्ट डीएलएल पर स्वचालित रूप से प्रतिलिपि बनाने के लिए सेमेक सेट किया है और चयनित विजुअल स्टूडियो संस्करण के आधार पर प्रकट किया है। सादगी के लिए मान लीजिए कि मैं MSVC90 के साथ काम कर रहा हूं। Redist कार्यक्रम निर्देशिका में प्रतिलिपि हो जाता है जब लेआउट इस तरह दिखता है:
| plugins/
| plugin1.dll
| plugin2.dll
| QtCore4.dll
| QtGui4.dll
| msvcm90.dll
| msvcp90.dll
| msvcr90.dll
| Microsoft.VC90.CRT.manifest (I'm also aware that this file is bugged in VS2008)
| program.exe
मैनिफ़ेस्ट फ़ाइल में बग के बारे में: http://www.cmake.org/pipermail/cmake/2008-September/023822.html
समस्या
इस लेआउट के साथ कार्यक्रम अब पर काम करता है जिन कंप्यूटरों में रेडिस्ट स्थापित नहीं है, लेकिन प्लगइन लोड नहीं हो रहे हैं। प्लगइन लोड करने के लिए मुझे निम्नलिखित में से एक करना है:
- मैनिफेस्ट फ़ाइल पर
plugins/
निर्देशिका पर कॉपी करें। मैनिफेस्ट फ़ाइल से msvc * .dll फ़ाइलों के सभी संदर्भों को हटा दें। यह काम करता है लेकिन यह अच्छा नहीं है क्योंकि मुझे प्रयुक्त एमएसवीसी के संस्करण के आधार पर संपादित मेनिफेस्ट फाइलों के विभिन्न संस्करणों का समर्थन करना होगा। साथ ही, मुझे नहीं पता कि यह 2008 के अलावा विजुअल स्टूडियो के साथ नहीं टूट जाएगा। - संपूर्ण रेडिस्ट को
plugins/
निर्देशिका में कॉपी करें। इसे मैनिफेस्ट फ़ाइल में किसी भी संशोधन की आवश्यकता नहीं है, लेकिन अबprogram.exe
बेवकूफ रूप से msvc * .dll फ़ाइलों को लोड करने की कोशिश करता है जो सोचते हैं कि वे प्लगइन हैं। स्वाभाविक रूप से, यह कृपा से विफल रहता है इसलिए कोई बड़ा नुकसान नहीं होता है। दूसरी कमी यह है कि कार्यक्रम पैकेज का आकार 1 एमबी से बढ़ता है। ये दोनों मुद्दे कुछ ऐसे हैं जिनके साथ मैं रह सकता हूं। - /एमटी स्विच के साथ प्लगइन संकलित करें। संक्षिप्त परीक्षण से पता चला है कि यह वास्तव में काम करता है लेकिन मुझे यकीन नहीं है कि अगर भविष्य में क्यूटी और
program.exe
दोनों/एमडी हैं तो यह भविष्य में कुछ भी नहीं तोड़ देगा।
सवाल (रों)
सबसे अच्छा समाधान क्या है? सही समाधान क्या है? यदि एक से अधिक सही समाधान हैं तो सबसे अच्छा अभ्यास कौन सा है? क्या मैं कभी ऐसा करने वाला पहला व्यक्ति हूं?
अद्यतन 1 (18 नवम्बर 2012)
सवाल अनुत्तरित बना हुआ है जबकि मैं मार्ग कि कम से कम सिरदर्द का कारण बनता है के लिए जाने का फैसला किया। अब तक मैं समाधान संख्या 1 का उपयोग कर रहा हूं और मैंने इसके साथ चिपकने का फैसला किया। यदि सीएमके का पता चलता है कि उपयोगकर्ता 2008 से अलग एमएसवीसी संस्करण का उपयोग कर रहा है तो यह एक चेतावनी संदेश प्रदर्शित करेगा कि स्वचालित पैकेजिंग पूरी तरह से समर्थित नहीं है।
आप अपने ऐप के लिए और आपके प्लगइन के लिए रन-टाइम क्यों स्थिर रूप से लिंक नहीं करते हैं? –
क्यूटी पहले से ही vcredist की आवश्यकता है, इसलिए मुझे इसे किसी भी तरह शामिल करना होगा। इसके अलावा संसाधन आवंटन के साथ समस्याएं हैं जब संसाधन एक स्थाई रूप से जुड़ी इकाई में आवंटित किया जाता है और फिर किसी अन्य में जारी किया जाता है - यह असुरक्षित है और प्रोग्राम क्रैश हो सकता है। मुझे नहीं पता कि क्यूटी/एमडी अगर क्यूटी के साथ कैसे व्यवहार करेगा। – ZalewaPL
मुझे लगता है कि आपको प्लगइन के लेखकों को यह तय करना चाहिए कि वे रन टाइम लाइब्रेरी से कैसे जुड़ना चाहते हैं और उन्हें रन टाइम के किसी विशेष संस्करण के विरुद्ध गतिशील रूप से लिंक करने की कोशिश न करें। आपके द्वारा उल्लिखित आवंटन मुद्दों के लिए, यदि आप किसी संसाधन को आवंटित करने के लिए प्लगइन में कॉल कर रहे हैं, तो आपको संसाधन को मुक्त करने के लिए प्लगइन में वापस कॉल करना चाहिए। –