2009-02-10 15 views
31

क्या एक स्थिर पुस्तकालय में संसाधन बनाना संभव है और पुस्तकालय से बस लिंक करके उनका पुन: उपयोग करना संभव है?एक स्थिर पुस्तकालय में वीसी ++ संसाधन

मैं मुख्य रूप से उस मामले के बारे में सोच रहा हूं जहां आप लाइब्रेरी में एक फ़ंक्शन कॉल करते हैं जो बदले में संसाधनों तक पहुंचता है।

उत्तर

22

यह किया जा सकता है, लेकिन यह काफी दर्दनाक है: आप इसे स्थिर पुस्तकालय से जोड़कर नहीं कर सकते हैं।

इस पर विचार करें: संसाधन EXE या DLL में एम्बेडेड हैं। जब स्थिर लाइब्रेरी में कुछ कोड कॉल (उदा।) लोड आइकन, तो यह EXE या DLL से संसाधन प्राप्त करेगा जो इसके साथ जुड़ा हुआ है। (उदाहरण के लिए)

  1. आप पुस्तकालय उन्हें मक्खी पर निर्माण कर सकते हैं, और उसके बाद का उपयोग CreateDialogIndirect:

    तो, अपने स्थिर पुस्तकालय संसाधन उपलब्ध होने की आवश्यकता है, तो आप विकल्पों में से एक जोड़े को मिल गया है। रेमंड चेन के "Building a dialog template at run-time" देखें।

  2. आप उन्हें लाइब्रेरी में सरल सरणी (यानी) char my_dialog_resource[] = { .... }; के रूप में एम्बेड कर सकते हैं, और फिर (उदा।) CreateDialogIndirect का उपयोग करें। आपको शायद .RES फ़ाइलों से .CPP फ़ाइलों में कनवर्ट करने वाली उपयोगिता (या लिखने) की आवश्यकता होगी।
  3. आप एलआईबी फ़ाइल को संसाधन स्क्रिप्ट (.RC फ़ाइल) और संबंधित शीर्षलेख फ़ाइल के साथ भेज सकते हैं। फिर आप #include उन्हें प्रासंगिक के रूप में देखते हैं। आपको LIB के उपयोग के लिए संसाधन आईडी की एक श्रृंखला आरक्षित करने की आवश्यकता होगी, ताकि वे मुख्य EXE या DLL के साथ टकराव न करें। एक स्थिर पुस्तकालय के रूप में उपयोग किए जाने पर एमएफसी करता है। या आप स्ट्रिंग संसाधन आईडी का उपयोग कर सकते हैं (यह STRINGTABLE संसाधनों के लिए काम नहीं करता है)।
  4. आपकी स्थिर लाइब्रेरी एक अलग संसाधन डीएलएल के साथ भेज सकती है।
+1

मैं वास्तव में अपने विकल्प 2 किया है, और यह सब है कि मुश्किल नहीं है। आपको .res फ़ाइल स्वरूप के लिए एक पार्सर भी बनाना होगा, जो अच्छी तरह से प्रलेखित है और बहुत भयानक नहीं है। – slicedlime

+1

@ रोगर लिप्सकोबे क्या आप किसी भी कारण से देख सकते हैं कि दीमित्री सी का जवाब अच्छा विचार क्यों नहीं है? – DataGraham

+1

क्योंकि .RES फ़ाइल को यह सुनिश्चित करने की आवश्यकता है कि यह संसाधन आईडी से टकराव न करे। मेरी # 3 में एक ही समस्या है, सिवाय इसके कि आप इसे कुछ प्रीप्रोसेसर जादू के साथ कम कर सकते हैं। आप दिमित्री के जवाब के साथ ऐसा नहीं कर सकते हैं। –

1

मुझे ऐसा नहीं लगता है। स्टेटिक लाइब्रेरी में इसका अपना नुकसान नहीं है। यह कोड डीएलएल या EXE के संदर्भ में निष्पादित किया गया है जो इसे लिंक करता है। यही कारण है कि आप सभी लाइब्रेरी के कोड से लोड करने का प्रयास करेंगे जो डीएलएल/एक्सई संलग्न करेंगे।

मैंने डीएलएल के साथ इस प्रकार के संसाधनों का पुन: उपयोग किया, जहां तक ​​इसकी अपनी पता स्थान है, और आप डीएलएल के हिस्टेंस के साथ लोडरसोर्स को कॉल कर सकते हैं।

0

अनुशंसित तरीका है कि आप अपनी लाइब्रेरी के साथ संसाधनों के साथ एक डीएल प्रदान करें।

10

मैं बस एमएस विजुअल स्टूडियो कंपाइलर के साथ इस माध्यम से चला गया। हम कुछ विरासत परियोजनाओं को डीएलएल से स्थिर पुस्तकालयों में परिवर्तित कर रहे थे। इनमें से कई डीएलएल में संवाद या स्ट्रिंग संसाधन थे। मैं इन मुख्य डीएलएल के लिए आरईसी स्क्रिप्ट को हमारे मुख्य एप्लिकेशन में संकलित करने में सक्षम था, जिसमें उन्हें मुख्य पाठ की आरसी स्क्रिप्ट फ़ाइल में "टेक्स्टिनकोड" तंत्र के माध्यम से शामिल किया गया था। मुझे सीधे आरसी फाइल को संपादित करके ऐसा करना सबसे आसान लगता है, लेकिन विजुअल स्टूडियो थोड़ा और "जादूगर" तंत्र भी प्रदान करता है। कार्यान्वयन अन्य compilers में सबसे अधिक संभावना है।

.1:


सीधे मुख्य आर सी स्क्रिप्ट में हेरफेर करने के लिए। "2 टेक्स्टिनक्यूएल" अनुभाग में, हेडर फ़ाइल शामिल करें जो आपकी लाइब्रेरी के लिए संसाधन आईडी को परिभाषित करती है। वाक्यविन्यास

2 TEXTINCLUDE 
BEGIN 
    "#include ""my_first_lib_header.h""\r\n" 
    "#include ""my_second_lib_header.h""\0" 
END 

.2। "3 टेक्स्टिनकोड" अनुभाग में, अपनी लाइब्रेरी से आरसी स्क्रिप्ट शामिल करें।

3 TEXTINCLUDE 
BEGIN 
    "#include ""my_first_library.rc""\r\n" 
    "#include ""my_second_library.rc""\0" 
END 

चरण 3 और 4 अपने आप ही हो जाना चाहिए, लेकिन मैंने पाया इसे और अधिक सिर्फ उन्हें अपने आप को दर्ज करने के लिए है, न कि माइक्रोसॉफ्ट के संसाधन स्क्रिप्ट संकलक के आधार पर चीजों की देखभाल करने के लिए की तुलना में विश्वसनीय था।

.3। अपने पुस्तकालय संसाधन के साथ हेडर फ़ाइल जोड़ें केवल पढ़ने के प्रतीकों की सूची में परिभाषित करता है। यह सूची आमतौर पर फ़ाइल के शीर्ष के पास होती है।

#define APSTUDIO_READONLY_SYMBOLS 
#include "my_first_lib_header.h" 
#include "my_second_lib_header.h" 
#undef APSTUDIO_READONLY_SYMBOLS 

.4। APSTUDIO_INVOKED अनुभाग में अपनी लाइब्रेरी की आरसी स्क्रिप्ट शामिल करें। यह आमतौर पर फ़ाइल के नीचे होता है।

#ifndef APSTUDIO_INVOKED 
#include "my_first_library.rc" 
#include "my_second_library.rc" 
#endif 

आप इस सब के विजुअल स्टूडियो IDE के माध्यम से स्वचालित रूप से भी कर सकते हैं, लेकिन मैं इसे हमेशा लागू नहीं किया था जब मैं इसे करने की उम्मीद पाया।

  1. विजुअल स्टूडियो में "संसाधन दृश्य" विंडो खोलें।
  2. अपने मुख्य एप्लिकेशन की संसाधन फ़ाइल पर राइट-क्लिक करें और संदर्भ मेनू से "संसाधन शामिल है ..." चुनें।
  3. "केवल-पढ़ने के निर्देश निर्देश" लेबल वाले बॉक्स में, .h फ़ाइलों के लिए विवरण शामिल करें जो आपके पुस्तकालयों के लिए संसाधन आईडी को परिभाषित करते हैं।
  4. "संकलन-समय निर्देश" लेबल वाले बॉक्स में, अपनी लाइब्रेरी की .rc स्क्रिप्ट के लिए विवरण शामिल करें।
  5. ठीक क्लिक करें। यह सुनिश्चित करने के लिए कि आप ऐसा करते हैं, आप आरसी स्क्रिप्ट संकलन मैन्युअल रूप से ट्रिगर भी कर सकते हैं।

अपनी लाइब्रेरी के संसाधन स्क्रिप्ट डिस्क पर किसी भी फाइल (पाठ फ़ाइलें, फ़ाइलें, आदि आइकन) का संदर्भ हैं, तो आप यह सुनिश्चित करें कि मुख्य आवेदन परियोजना जानता है, जहां उन्हें खोजने के लिए करने की आवश्यकता होगी। आप या तो इन फ़ाइलों को कहीं भी कॉपी कर सकते हैं आपका एप्लिकेशन उन्हें ढूंढ सकता है या आप कंपाइलर सेटिंग्स में एक अतिरिक्त शामिल पथ जोड़ सकते हैं।

को जोड़ने के लिए एक अतिरिक्त पथ में शामिल हैं:

  1. गुण अपने मुख्य आवेदन के लिए संवाद खोलें।
  2. बाएं हाथ नेविगेशन फलक से "कॉन्फ़िगरेशन गुण/संसाधन/सामान्य" का चयन करें।
  3. गुण सूची में, "अतिरिक्त शामिल निर्देशिकाएं" के बगल में कोई भी प्रासंगिक पथ दर्ज करें।
+1

धन्यवाद! यह मेरा दिन बचाया! हालांकि मैं वीएस -2010 पर शीर्षलेखों को शामिल करने में सक्षम था। यह काम करने के बाद मैंने .rc फ़ाइलों के लिए दो प्रविष्टियों को जोड़ा। – lowglider

48

केवल एक चीज आप विज़ुअल सी में एक स्थिर पुस्तकालय में संसाधनों (चित्र, संवाद, आदि ...) उपयोग करने के लिए क्या करने की जरूरत ++ (2008), शामिल स्थिर लाइब्रेरी की संबद्ध .res में फ़ाइल है आपके परियोजना। यह "परियोजना सेटिंग्स/लिंकर/इनपुट/अतिरिक्त निर्भरताओं" पर किया जा सकता है।

इस समाधान के साथ, स्थैतिक पुस्तकालय के संसाधन .exe में पैक किए गए हैं, इसलिए आपको अतिरिक्त DLL की आवश्यकता नहीं है। अफसोस की बात है, विजुअल स्टूडियो में .lib फ़ाइल के लिए स्वचालित रूप से .res फ़ाइल शामिल नहीं होती है (जब "प्रोजेक्ट निर्भरता" -फेचर का उपयोग करते समय), लेकिन मुझे लगता है कि यह छोटा अतिरिक्त चरण स्वीकार्य है।

मैंने इस समाधान के लिए बहुत लंबा समय देखा है, और अब यह आश्चर्य की बात है कि यह इतना आसान है। एकमात्र समस्या यह है कि यह पूरी तरह से अनियंत्रित है।

+1

यह शायद मूल प्रश्न के लिए नहीं पूछा गया था, लेकिन यह मेरा दिन बचाया! +1 – kizzx2

+0

मेरे लिए भी बहुत अच्छा काम किया! @ kizzx2 मैं सहमत हूं कि सवाल वास्तव में क्या नहीं पूछा गया है, लेकिन मुझे लगता है कि यह अंतिम लक्ष्य पूरा करता है। – DataGraham

+0

कोई विचार यह कैसे हाथ से लिखित मेकफ़ाइल में किया जाता है? मैं यहां एक दस्तावेज संकलक विकल्प या प्रगति को याद कर रहा हूं। – Lothar

0

विजुअल स्टूडियो 2010 के अनुसार, माइक्रोसॉफ्ट के विकास उपकरण स्पष्ट रूप से स्थिर पुस्तकालयों के अंदर संकलित संसाधन डेटा को सही ढंग से संभाल नहीं सकते हैं।

एक संकलित संसाधन फ़ाइल (एक .res फ़ाइल), आपके पास दो विकल्प वितरित करने के लिए:

  1. अलग से वितरित करें .res फ़ाइलें, और उनके खिलाफ लिंक करने के लिए ग्राहक कोड हिदायत;
  2. cvtres का उपयोग कई .res फ़ाइलों को एक ही ऑब्जेक्ट (.obj) फ़ाइल में विलय करने के लिए करें, और इसे अलग से प्रदान करें।

ध्यान दें कि आप cvtres के साथ बनाई गई वस्तु फ़ाइलों में लिब नहीं कर सकते। यदि एकाधिक ऑब्जेक्ट फ़ाइलें प्रदान की जाती हैं, तो lib शिकायत करता है कि एकाधिक .res फ़ाइलों को दिया गया था; यदि एक ऑब्जेक्ट फ़ाइल प्रदान की जाती है, तो lib शिकायत नहीं करता है, लेकिन लिंकर आसानी से lib फ़ाइल में एम्बेडेड संसाधन डेटा को अनदेखा करता है।

यह मामला पढ़ सकते हैं और संसाधन डेटा में libbed लिंक (कुछ कमांड लाइन विकल्प, खंड हेरफेर और इतने पर के साथ), संसाधन डेटा के बाद से करने के लिए लिंकर मजबूर करने के लिए एक तरीका है कि हो सकता है में वास्तव में उपलब्ध है पुस्तकालय (dumpbin बताता है)। अब तक, मुझे कोई समाधान नहीं मिला है, और, जब तक कोई विकास उपकरण को हैक करने के इच्छुक नहीं है, इस सरल समाधान से बेहतर कुछ भी संभवतः प्रयास के लायक नहीं है।

एक स्थिर पुस्तकालय में संसाधन डेटा भेजने का एकमात्र तरीका (इस मामले में, एक स्थिर लाइब्रेरी के साथ) संसाधनों को अलग से वितरित करना और स्पष्ट रूप से उन्हें क्लाइंट कोड में लिंक करना है। cvtres का उपयोग करके वितरित संसाधन फ़ाइलों की संख्या को एक में कम कर सकते हैं, यदि उनमें से कई हैं।

-2

जब निम्न विधि का उपयोग किया जाता है, तो किसी भी संसाधन (इस उदाहरण में, एक आइकन) को स्थिर पुस्तकालय के अभिन्न अंग के रूप में उपयोग किया जा सकता है और ऐसी लाइब्रेरी किसी भी प्रकार के एप्लिकेशन द्वारा उपयोग की जा सकती है, जिसमें एक कंसोल एक (कोई भी संसाधन खंड नहीं है)।

  1. आइकन बीईटीई की एक स्थिर सरणी में परिवर्तित हो गया है। इसके लिए bin2c का उपयोग किया जा सकता है।
  2. डेटा एक HICON हैंडल में परिवर्तित किया गया है। यहाँ मैं यह कैसे किया है:

    HICON GetIcon() 
    { 
        DWORD dwTmp; 
        int offset; 
        HANDLE hFile; 
        HICON hIcon = NULL; 
        offset = LookupIconIdFromDirectoryEx(s_byIconData, TRUE, 0, 0, LR_DEFAULTCOLOR); 
        if (offset != 0) 
        { 
         hIcon = CreateIconFromResourceEx(s_byIconData + offset, 0, TRUE, 0x00030000, 0, 0, LR_DEFAULTCOLOR | LR_DEFAULTSIZE); 
        } 
        return hIcon; 
    } 
    
  3. GetIcon LoadIcon के बजाय प्रयोग किया जाता है। बुला के बजाय:

m_hIcon = ::LoadIcon(hInstanceIcon, MAKEINTRESOURCE(pXMB->nIcon));

फिर फोन

m_hIcon = GetIcon() 
संबंधित मुद्दे