डायनेमिक बनाम स्टेटिक लाइब्रेरी का उपयोग कब करें


437

C ++ में क्लास लाइब्रेरी बनाते समय, आप डायनेमिक ( .dll, .so) और स्टैटिक ( .lib, .a) लाइब्रेरी के बीच चयन कर सकते हैं । उनके बीच क्या अंतर है और कब कौन सा उपयोग करना उचित है?


2
ऐसा लगता है वहाँ भी कुछ है जो "आयात लाइब्रेरी" चेक कहा जाता है कि stackoverflow.com/questions/3573475/...
वाकान टंका

जवाबों:


299

स्टेटिक लाइब्रेरी आपके बाइनरी में कोड का आकार बढ़ाती हैं। वे हमेशा लोड होते हैं और आपके द्वारा संकलित कोड का कोई भी संस्करण उस कोड का संस्करण होता है जो चलेगा।

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

इसके अतिरिक्त डायनेमिक लाइब्रेरियों को आवश्यक रूप से लोड नहीं किया जाता है - वे आमतौर पर लोड होते हैं जब पहली बार कहा जाता है - और उन घटकों के बीच साझा किया जा सकता है जो एक ही लाइब्रेरी (कई डेटा लोड, एक कोड लोड) का उपयोग करते हैं।

डायनेमिक पुस्तकालयों को ज्यादातर समय बेहतर दृष्टिकोण माना जाता था, लेकिन मूल रूप से उनमें एक प्रमुख दोष (गूगल डीएलएल नरक) था, जिसे सभी को खत्म कर दिया गया है, लेकिन हाल के विंडोज ओएस (विशेष रूप से विंडोज एक्सपी) द्वारा समाप्त कर दिया गया है।


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

5
मैक पर, मैं बहुत सारे गतिशील पुस्तकालयों का उपयोग करता हूं। उदाहरण के लिए, मैक ओएस एक्स में sqlite3 एम्बेड है। मैंने एक प्रोग्राम बनाया जिसमें प्रदर्शन भंडारण के लिए एक sqlite3 डेटाबेस सुविधा है। हालाँकि, क्योंकि यह शायद ही कभी गतिशील लिंकिंग का उपयोग संकलित समय पर बचाता है, परीक्षण को आसान / तेज़ बनाता है, हालाँकि अगर मैं रिलीज़ संस्करण बनाने वाला था, तो मुझे लगता है कि मैं हमेशा अनुकूलता के मामले में सिर्फ स्थैतिक पुस्तकालय का उपयोग
करूंगा

6
@Zifre: relocatable = को अलग-अलग वर्चुअल पते पर लोड किया जा सकता है। DLL निश्चित रूप से इसका समर्थन करता है।
dma_k

20
@dma_k: विंडोज DLL को अलग-अलग पते पर लोड किया जा सकता है, लेकिन केवल इसलिए कि लिंकर सभी कोड को कॉपी करता है और पता नंबर बदलता है। साझा किए गए ऑब्जेक्ट के साथ, सभी पता संदर्भ रिश्तेदार हैं, इसलिए कई प्रक्रियाएं साझा किए गए ऑब्जेक्ट के लिए एक ही मेमोरी साझा कर सकती हैं। दूसरे शब्दों में, विंडोज पर, ए 1 एमबी डीएलएल 3 कार्यक्रमों = 3 एमबी द्वारा उपयोग किया जाता है। Linux पर, A MB SO का उपयोग 3 प्रोग्राम = 1 MB द्वारा किया जाता है।
जिफरे

7
विंडोज और लिनक्स दोनों में साझा पुस्तकालयों के लोड-टाइम के स्थानांतरण की अवधारणा है eli.thegreenplace.net/2011/08/25/… सबसे बड़ी बात यह है कि स्थिति स्वतंत्र कोड की अनुमति लिनक्स के लिए कुछ खास नहीं था, बल्कि RIP- सापेक्ष पते जोड़ा गया x64 अनुदेश सेट के साथ; Windows और Linux दोनों RIP के उपयोग से बना सकते हैं, संबोधन पुस्तकालयों को स्थानांतरित करते समय फिक्सअप की संख्या को कम करते हैं।
क्लीमाहियू

194

दूसरों ने पर्याप्त रूप से समझाया है कि एक स्थिर पुस्तकालय क्या है, लेकिन मैं स्टैटिक लाइब्रेरीज़ का उपयोग करने के कुछ संकेतों को इंगित करना चाहता हूं, जैसे कि विंडोज़ पर:

  • एकमात्र: यदि किसी चीज़ को वैश्विक / स्थिर और अद्वितीय होना चाहिए, तो उसे स्थिर पुस्तकालय में रखने के बारे में बहुत सावधानी बरतें। यदि कई डीएलएल उस स्थिर पुस्तकालय से जुड़े होते हैं, तो वे एकल की अपनी प्रति प्राप्त करेंगे। हालाँकि, यदि आपका एप्लिकेशन एक एकल EXE है जिसमें कोई कस्टम DLL नहीं है, तो यह समस्या नहीं हो सकती है।

  • अपरिष्कृत कोड हटाना: जब आप किसी स्थैतिक पुस्तकालय से लिंक करते हैं, तो केवल आपके DLL / EXE द्वारा संदर्भित स्थिर पुस्तकालय के भाग आपके DLL / EXE में लिंक हो जाएंगे।

    उदाहरण के लिए, यदि mylib.libइसमें a.objऔर b.objआपका DLL / EXE केवल संदर्भ फ़ंक्शन या चर हैं a.obj, b.objतो लिंकर द्वारा संपूर्णता को छोड़ दिया जाएगा। यदि b.objवैश्विक / स्थिर वस्तुएं हैं, तो उनके निर्माता और विध्वंसक निष्पादित नहीं होंगे। यदि उन निर्माणकर्ताओं / विध्वंसक के दुष्प्रभाव होते हैं, तो आप उनकी अनुपस्थिति से निराश हो सकते हैं।

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

    इसका एक और परिणाम यह है कि एक स्थिर लाइब्रेरी में ऑब्जेक्ट फाइलें हो सकती हैं जो कि अनसुलझे संदर्भों के कारण पूरी तरह से अनुपयोगी होती हैं, लेकिन जब तक आप उन ऑब्जेक्ट फ़ाइलों से किसी फ़ंक्शन या चर का संदर्भ नहीं देते हैं, तब तक यह लिंकर त्रुटि का कारण नहीं होगा। यह लाइब्रेरी लिखे जाने के लंबे समय बाद हो सकता है।

  • डिबग प्रतीक: आप प्रत्येक स्थिर पुस्तकालय के लिए एक अलग पीडीबी चाहते हैं, या आप डिबग प्रतीकों को ऑब्जेक्ट फ़ाइलों में रखना चाह सकते हैं ताकि वे डीएलएल / एक्सई के लिए पीडीबी में लुढ़क जाएं। विजुअल C ++ डॉक्यूमेंटेशन आवश्यक विकल्पों की व्याख्या करता है

  • RTTI:type_info यदि आप एक ही स्थिर पुस्तकालय को कई DLL में जोड़ते हैं तो आप एक ही वर्ग के लिए कई वस्तुओं के साथ समाप्त हो सकते हैं । यदि आपका प्रोग्राम मानता है कि type_info"सिंगलटन" डेटा और उपयोग करता है &typeid()या type_info::before(), आपको अवांछनीय और आश्चर्यजनक परिणाम मिल सकते हैं।


23
एकल के बारे में बात के लिए, यह मत भूलो कि एक DLL कई बार लोड किया जा सकता है (एक ही संस्करण या mulitple संस्करण) और अभी भी कोई एकल गारंटी नहीं है।
ओरियन एड्रियन

अपरिवर्तित कोड हटाने के बारे में अतिरिक्त बिंदु: DLL के लिए किए गए कॉल को संदर्भित DLL को लोड करने के लिए बाध्य करने के लिए वास्तविक कॉल की आवश्यकता होती है। इसे एक संदर्भ के रूप में जोड़ते हैं, लेकिन फिर किसी भी कॉल को शामिल नहीं करते हैं जो इसे संदर्भित करता है फिर भी आपको एक स्थिर परिवाद होने के समान परिणाम मिलेगा जो कुछ भी कॉल नहीं करता है। फर्क सिर्फ इतना है कि वास्तव में जहाज क्या है। दोनों मामलों में स्थिर कंस्ट्रक्टर और डिस्ट्रक्टर्स आग नहीं लगाते हैं।
ओरियन एड्रियन

@ bk1e ऐसा नहीं होना चाहिए। .A हमेशा सभी प्रतीकों के साथ बनाया गया था। जब यह स्थिर अपने आवेदन में दिए गए लिंक पर, हाँ केवल उन प्रतीकों कि उपयोग किया जाता है में लिंक किया जाएगा।
मीलों राउत

62

एक lib कोड की एक इकाई है जिसे आपके एप्लिकेशन निष्पादन योग्य के भीतर बंडल किया जाता है।

एक dll निष्पादन योग्य कोड की एक स्वसंपूर्ण इकाई है। यह उस प्रक्रिया में लोड होता है, जब उस कोड में कॉल किया जाता है। एक dll का उपयोग कई अनुप्रयोगों द्वारा किया जा सकता है और कई प्रक्रियाओं में लोड किया जा सकता है, जबकि हार्ड ड्राइव पर अभी भी कोड की केवल एक ही कॉपी है।

Dll पेशेवरों : कई उत्पादों के बीच कोड का पुन: उपयोग / साझा करने के लिए इस्तेमाल किया जा सकता है; मांग पर प्रक्रिया मेमोरी में लोड और जब ज़रूरत नहीं हो तो अनलोड किया जा सकता है; कार्यक्रम के बाकी हिस्सों से स्वतंत्र रूप से उन्नत किया जा सकता है।

Dll विपक्ष : dll लोडिंग और कोड रिबासिंग का प्रदर्शन प्रभाव; वर्जनिंग समस्याएं ("dll नरक")

लीब पेशेवरों : कोई प्रदर्शन प्रभाव नहीं क्योंकि कोड हमेशा प्रक्रिया में लोड होता है और छूट नहीं दी जाती है; कोई संस्करण समस्याओं।

Lib cons : निष्पादन योग्य / प्रक्रिया "ब्लोट" - सभी कोड आपके निष्पादन योग्य हैं और प्रक्रिया शुरू होने पर लोड किए गए हैं; कोई पुन: उपयोग / साझा नहीं - प्रत्येक उत्पाद कोड की अपनी प्रति है।


रिबासिंग का निर्माण रिबास। Exe का उपयोग करके या लिंक करने के लिए / BASE विकल्प पास करके भी किया जा सकता है। यह प्रभावी है या नहीं यह इस बात पर निर्भर करता है कि क्या रनटाइम के दौरान कोई अप्रत्याशित पता स्थान टकराव होता है।
bk1e

24

स्थिर बनाम गतिशील पुस्तकालयों के तकनीकी निहितार्थ के अलावा (स्थिर फाइलें एक बड़े बाइनरी बनाम गतिशील पुस्तकालयों में सब कुछ बंडल करती हैं जो कई अलग-अलग निष्पादनयोग्य के बीच कोड साझा करने की अनुमति देती हैं), कानूनी निहितार्थ हैं

उदाहरण के लिए, यदि आप LGPL लाइसेंस कोड का उपयोग कर रहे हैं और आप LGPL लाइब्रेरी के खिलाफ स्टेटिकली लिंक करते हैं (और इस तरह एक बड़ा बाइनरी बनाते हैं), तो आपका कोड अपने आप ही ओपन सॉरर्ड ( फ्रीडम इन फ्रीडम) LGPL कोड बन जाता है । यदि आप एक साझा वस्तुओं के खिलाफ लिंक करते हैं, तो आपको केवल एलजीपीएल पुस्तकालय में किए गए सुधार / बग फिक्स को एलजीपीएल करने की आवश्यकता है।

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


23

C ++ प्रोग्राम दो चरणों में बनाए जाते हैं

  1. संकलन - वस्तु कोड (.obj) का उत्पादन करता है
  2. जोड़ने - निष्पादन योग्य कोड (.exe या .dll) का उत्पादन करता है

स्टेटिक लाइब्रेरी (.lib) सिर्फ .obj फाइलों का एक बंडल है और इसलिए यह एक संपूर्ण कार्यक्रम नहीं है। यह एक कार्यक्रम के निर्माण के दूसरे (लिंकिंग) चरण से नहीं गुजरा है। दूसरी ओर, Dlls, exe की तरह हैं और इसलिए पूर्ण कार्यक्रम हैं।

यदि आप एक स्थैतिक पुस्तकालय का निर्माण करते हैं, तो यह अभी तक जुड़ा नहीं है और इसलिए आपके स्थैतिक पुस्तकालय के उपभोक्ताओं को उसी संकलक का उपयोग करना होगा जो आपने उपयोग किया था (यदि आपने g ++ का उपयोग किया है, तो उन्हें g ++ का उपयोग करना होगा)।

यदि इसके बजाय आपने एक dll बनाया (और इसे सही तरीके से बनाया है ), तो आपने एक पूरा प्रोग्राम बनाया है, जिसका उपयोग सभी उपभोक्ता कर सकते हैं, चाहे वह कोई भी कंपाइलर इस्तेमाल कर रहे हों। हालांकि, कई प्रतिबंध हैं, एक dll से निर्यात करने पर, यदि क्रॉस कंपाइलर संगतता वांछित है।


1
यह मेरे लिए समाचार है। DLL का उपयोग करते समय क्रॉस कंपाइलर्स के साथ क्या प्रतिबंध हैं? एक ही टूलकिन की आवश्यकता के बिना प्रोग्रामर का निर्माण करने के बाद DLLs के लिए एक विशाल प्लस जैसा लगता है
Dan

1
यह उत्तर जानकारीपूर्ण है। मामूली कैविटी जोड़ना: consumers of your static library will have to use the same compiler that you usedयदि स्टैटिक लाइब्रेरी C ++ लाइब्रेरी का उपयोग करती है, जैसे #include <iostream>
truthadjustr

जब तक एक ही संकलक का उपयोग नहीं किया जाता है तब तक कोई c ++ dll का उपभोग नहीं कर सकता है (क्योंकि मानक c ++ abi नहीं है, प्रतीकों को अलग-अलग तरीकों से मंगवाया गया है)। Dll और क्लाइंट मॉड्यूल दोनों को एक ही कंपाइलर और एक ही बिल्ड सेटिंग्स का उपयोग करना होगा
kcris

19

स्टैटिक लाइब्रेरी बनाना

$$:~/static [32]> cat foo.c
#include<stdio.h>
void foo()
{
printf("\nhello world\n");
}
$$:~/static [33]> cat foo.h
#ifndef _H_FOO_H
#define _H_FOO_H

void foo();

#endif
$$:~/static [34]> cat foo2.c
#include<stdio.h>
void foo2()
{
printf("\nworld\n");
}
$$:~/static [35]> cat foo2.h
#ifndef _H_FOO2_H
#define _H_FOO2_H

void foo2();

#endif
$$:~/static [36]> cat hello.c
#include<foo.h>
#include<foo2.h>
void main()
{
foo();
foo2();
}
$$:~/static [37]> cat makefile
hello: hello.o libtest.a
        cc -o hello hello.o -L. -ltest
hello.o: hello.c
        cc -c hello.c -I`pwd`
libtest.a:foo.o foo2.o
        ar cr libtest.a foo.o foo2.o
foo.o:foo.c
        cc -c foo.c
foo2.o:foo.c
        cc -c foo2.c
clean:
        rm -f foo.o foo2.o libtest.a hello.o

$$:~/static [38]>

एक गतिशील पुस्तकालय का निर्माण

$$:~/dynamic [44]> cat foo.c
#include<stdio.h>
void foo()
{
printf("\nhello world\n");
}
$$:~/dynamic [45]> cat foo.h
#ifndef _H_FOO_H
#define _H_FOO_H

void foo();

#endif
$$:~/dynamic [46]> cat foo2.c
#include<stdio.h>
void foo2()
{
printf("\nworld\n");
}
$$:~/dynamic [47]> cat foo2.h
#ifndef _H_FOO2_H
#define _H_FOO2_H

void foo2();

#endif
$$:~/dynamic [48]> cat hello.c
#include<foo.h>
#include<foo2.h>
void main()
{
foo();
foo2();
}
$$:~/dynamic [49]> cat makefile
hello:hello.o libtest.sl
        cc -o hello hello.o -L`pwd` -ltest
hello.o:
        cc -c -b hello.c -I`pwd`
libtest.sl:foo.o foo2.o
        cc -G -b -o libtest.sl foo.o foo2.o
foo.o:foo.c
        cc -c -b foo.c
foo2.o:foo.c
        cc -c -b foo2.c
clean:
        rm -f libtest.sl foo.o foo

2.o hello.o
$$:~/dynamic [50]>

13

एक स्थिर पुस्तकालय क्लाइंट में संकलित हो जाता है। A .lib का संकलन समय पर किया जाता है और लाइब्रेरी की सामग्री उपभोग्य निष्पादन योग्य हो जाती है।

एक गतिशील लाइब्रेरी को रनटाइम पर लोड किया जाता है और क्लाइंट निष्पादन योग्य में संकलित नहीं किया जाता है। डायनेमिक लाइब्रेरी अधिक लचीली होती हैं क्योंकि कई क्लाइंट एक्जीक्यूटिव एक DLL लोड कर सकते हैं और इसकी कार्यक्षमता का उपयोग कर सकते हैं। यह आपके ग्राहक कोड की समग्र आकार और स्थिरता को न्यूनतम रखता है।


13

आपको समय, परिवर्तन, स्थिरता, अनुकूलता आदि के परिवर्तनों के बारे में ध्यान से सोचना चाहिए।

यदि साझा कोड का उपयोग करने वाले दो ऐप हैं, तो क्या आप उन ऐप्स को एक साथ बदलने के लिए मजबूर करना चाहते हैं, यदि उन्हें एक-दूसरे के साथ संगत होने की आवश्यकता है? फिर dll का उपयोग करें। एक्सई के सभी एक ही कोड का उपयोग करेंगे।

या क्या आप उन्हें एक-दूसरे से अलग करना चाहते हैं, ताकि आप एक को बदल सकें और आश्वस्त रहें कि आपने दूसरे को नहीं तोड़ा है। फिर स्थैतिक परिवाद का उपयोग करें।

DLL नरक है जब आप शायद एक स्थिर काम का इस्तेमाल किया है, लेकिन आप बजाय एक dll का इस्तेमाल किया है, और सभी exes इसके साथ अनुकूल नहीं हैं।


9

एक स्थिर पुस्तकालय को अंतिम निष्पादन योग्य में जोड़ा जाना चाहिए; यह निष्पादन योग्य का हिस्सा बन जाता है और जहां भी जाता है, उसका अनुसरण करता है। हर बार निष्पादन योग्य निष्पादित होने पर एक डायनेमिक लाइब्रेरी लोड की जाती है और DLL फ़ाइल के रूप में निष्पादन योग्य से अलग रहती है।

आप DLL का उपयोग तब करेंगे जब आप निष्पादन योग्य को फिर से लिंक किए बिना लाइब्रेरी द्वारा प्रदान की गई कार्यक्षमता को बदलना चाहते हैं (बस DLL फ़ाइल को बदलें, निष्पादन योग्य फ़ाइल को बदलने के बिना)।

जब भी आपके पास डायनेमिक लाइब्रेरी का उपयोग करने का कोई कारण नहीं है, तो आप एक स्थिर पुस्तकालय का उपयोग करेंगे।


आप एक DLL भी उपयोग कर सकते हैं जब कई अन्य अनुप्रयोग समान कार्यक्षमता का उपयोग करते हैं - यह पदचिह्न को कम कर सकता है।
टिम

इसके अलावा, अपनी प्रारंभिक अवधारणा, "प्लग-इन" आर्किटेक्चर का विस्तार करना, जहां आप बाद में पुनर्निर्माण / पुन: जारी किए बिना जोड़ा / अज्ञात कार्यक्षमता को अनुमति देना चाहते हैं, केवल गतिशील पुस्तकालयों के साथ किया जा सकता है।
टिम

8

उलरिक ड्रेपर का पेपर " हाउ टू राइट शेयरेड लाइब्रेरीज़ " पर भी अच्छा संसाधन है जो यह बताता है कि साझा पुस्तकालयों का लाभ उठाने के लिए सबसे अच्छा विवरण क्या है, या वह "डायनामिक साझा ऑब्जेक्ट्स" (डीएसओ) के रूप में क्या संदर्भित करता है। यह ईएलएफ बाइनरी प्रारूप में साझा पुस्तकालयों पर अधिक ध्यान केंद्रित करता है, लेकिन कुछ चर्चाएं विंडोज डीएलएल के लिए भी उपयुक्त हैं।


5

इस विषय की एक उत्कृष्ट चर्चा के लिए सूर्य के इस लेख को पढ़ें।

यह सभी लाभों में चला जाता है जिसमें इंटरपोज़िंग लाइब्रेरी सम्मिलित करने में सक्षम है। इंटरपोज़िंग पर अधिक विवरण यहां इस लेख में पाया जा सकता है


4

वास्तव में आप जो व्यापार कर रहे हैं (एक बड़ी परियोजना में) प्रारंभिक लोड समय में है, पुस्तकालयों को एक या दूसरे समय में लिंक किया जा रहा है, जो निर्णय लेना है, वह लिंक काफी लंबा समय लेगा, जिसे कंपाइलर की आवश्यकता है बुलेट को काटने के लिए और इसे आगे बढ़ाएं, या डायनेमिक लिंकर लोड समय पर कर सकते हैं।


3

यदि आपकी लाइब्रेरी को कई निष्पादकों के बीच साझा किया जा रहा है, तो यह अक्सर निष्पादकों के आकार को कम करने के लिए इसे गतिशील बनाने के लिए समझ में आता है। अन्यथा, निश्चित रूप से इसे स्थिर करें।

एक dll का उपयोग करने के कई नुकसान हैं। इसे लोड करने और उतारने के लिए अतिरिक्त ओवरहेड है। एक अतिरिक्त निर्भरता भी है। यदि आप इसे अपने निष्पादकों के साथ असंगत बनाने के लिए dll को बदलते हैं, तो वे काम करना बंद कर देंगे। दूसरी ओर, यदि आप एक स्थिर पुस्तकालय बदलते हैं, तो पुराने संस्करण का उपयोग करने वाले आपके संकलित निष्पादनयोग्य प्रभावित नहीं होंगे।


3

यदि लाइब्रेरी स्थिर है, तो लिंक समय पर कोड आपके निष्पादन योग्य के साथ जुड़ा हुआ है। यह आपके निष्पादन योग्य को बड़ा बनाता है (यदि आप गतिशील मार्ग से चले गए हैं)।

यदि लाइब्रेरी गतिशील है, तो लिंक समय पर आवश्यक तरीकों के संदर्भ आपके निष्पादन योग्य में बनाए जाते हैं। इसका मतलब है कि आपको अपने निष्पादन योग्य और गतिशील पुस्तकालय को शिप करना होगा। आपको यह भी विचार करना चाहिए कि क्या अन्य सामानों के बीच पुस्तकालय में कोड का साझा उपयोग सुरक्षित, पसंदीदा लोड पता है।

यदि आप स्थैतिक पुस्तकालय के साथ रह सकते हैं, तो स्थैतिक पुस्तकालय के साथ जाएं।


3

हम अपने प्रोजेक्ट में बहुत सारे DLL (> 100) का उपयोग करते हैं। इन DLL की एक-दूसरे पर निर्भरता है और इसलिए हमने डायनेमिक लिंकिंग का सेटअप चुना। हालाँकि इसके निम्नलिखित नुकसान हैं:

  • धीमी गति से स्टार्टअप (> 10 सेकंड)
  • DLL को संस्करणित किया जाना था, क्योंकि विंडोज़ नामों की विशिष्टता पर मॉड्यूल लोड करता है। स्वयं के लिखित घटकों को अन्यथा DLL का गलत संस्करण मिलेगा (अर्थात जो पहले से ही वितरित वितरण के बजाय पहले से लोड है)
  • ऑप्टिमाइज़र केवल DLL सीमाओं के भीतर अनुकूलन कर सकता है। उदाहरण के लिए, अनुकूलक एक दूसरे के बगल में अक्सर उपयोग किए गए डेटा और कोड को रखने की कोशिश करता है, लेकिन यह DLL सीमाओं के पार काम नहीं करेगा

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

  • exe शेयर्ड_लिब 1, शेयर्ड_लिब 2 का उपयोग करता है
  • share_lib1 साझा करें_lib2 का उपयोग करें
  • shared_lib2

साझा_लिब 2 का कोड और चर अंतिम विलयित निष्पादन योग्य में केवल एक बार मौजूद होना चाहिए। क्या कोई इस सवाल का समर्थन कर सकता है?


क्या आप कोड के दोहराव से बचने के लिए किसी तरह से कुछ पूर्व-संकलक निर्देशों का उपयोग करने के लिए नहीं थे?
पेसमैन

Afaiac precompiling केवल प्रति मॉड्यूल (exe / dll / lib) आधार पर काम करता है। Precompiling प्राथमिक रूप से संकलन को गति देने के लिए है, हालांकि यह संकलन इकाई के भीतर कई समावेशन को भी रोकता है। हालांकि शामिल गार्ड इस प्रभाव को प्राप्त करने का बेहतर तरीका है।
Gast128

2

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


2

यदि आपका एम्बेडेड प्रोजेक्ट्स या विशेष प्लेटफ़ॉर्म पर काम करने वाले स्टैटिक लाइब्रेरीज़ ही जाने का एकमात्र तरीका हैं, तो भी कई बार वे आपके आवेदन में संकलित करने की परेशानी से कम नहीं होते हैं। इसके अलावा परियोजनाओं और मेकफाइल जिसमें सब कुछ शामिल है, जीवन को खुशहाल बनाता है।


2

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

यदि आपके पास एक पुस्तकालय है जो बाकी के कोडबेस (उदाहरण के लिए एक तीसरा पक्ष पुस्तकालय) से पूरी तरह से अलग है, तो इसे एक dll बनाने पर विचार करें। यदि लाइब्रेरी LGPL है, तो आपको लाइसेंस शर्तों के कारण किसी भी समय dll का उपयोग करने की आवश्यकता हो सकती है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.