c - Can I modify a shared library file to work fine with my executable -


मैंने पुस्तकालय फ़ाइल को abc.so कहते हैं जो कि ( ac , बीसी , cc ) फ़ाइलें। अब मैं एक्जीक्यूटेबल से कहता हूं target.out

मेरा संदेह है ... क्या मैं abc.so को हटा सकता हूं और अलग से फिर से Abc.so से ( एसी , bc , cc ) और इसे मेरे पहले abc.so कोड> मौजूद था हालांकि मेरा target.out पुराना है।

अब अगर मैं target.out चलाता हूं तो यह नया abc के साथ ठीक काम करेगा। इसलिए ??

हाँ यह काम करेगा, लेकिन आपको सावधान रहना होगा।

चलो उदाहरण के रूप में लेते हैं:

  int my_global_var = 42; Int राशि (int a, int b) {वापसी a + b; }   

इसे इसके साथ बनाया जा सकता है:

  gcc -fPIC -shared-o libtest.so libtest.c   < p>  readelf -s libtest.so  के साथ हम देख सकते हैं कि फ़ंक्शन और वैश्विक वैरिएबल को सार्वजनिक प्रतीकों के रूप में उजागर किया गया था:  
  $ readelf -s libtest.so 42 : 0000000000200950 4 ऑब्जेक्ट ग्लोबल डिफॉल्ट 21 my_global_var ... 47: 0000000000000665 42 एफआईएनसी वैश्विक डिफाल्ट 11 राशि ...   

यह ध्यान देने योग्य है कि .so फ़ाइल इन प्रतीकों के प्रकारों या प्रोटोटाइप को निर्दिष्ट नहीं करता है।

अब हम एक प्रोग्राम लिखते हैं जो कि lib का उपयोग करता है:

  #include & lt; stdio.h & gt; / * Libtest * / int योग (int, int) द्वारा प्रदान की गई; एक्सटर्न इंट my_global_var; Int main () {printf ("5 + 2 =% d और my_global_var =% d \ n", योग (5, 2), my_global_var); वापसी 0; }   

और इसे बनाएं:

  जीसीसी-एल यह काम करता है:  
  $ ./program5 + 2 = 7 और my_global_var = 42     / प्री> 

हम देख सकते हैं कि प्रोग्राम गतिशील रूप से libtest.so :

  $ ldd प्रोग्राम से जुड़ा हुआ है ... libtest .so (0x00007f1138c70000) ...   

एक बार फिर प्रतीकों sum और my_global_var प्रोग्राम के शीर्षलेखों में टाइप या प्रोटोटाइप के बिना संदर्भित हैं :

  $ objdump --dynamic-reloc कार्यक्रम DYNAMIC पुनर्वास रिकॉर्ड्स OFFSET प्रकार मान 0000000000600b00 R_X86_64_GLOB_DAT __gmon_start__ 0000000000600b50 R_X86_64_COPY my_global_var 0000000000600b20 R_X86_64_JUMP_SLOT printf 0000000000600b28 R_X86_64_JUMP_SLOT __libc_start_main 0000000000600b30 R_X86_64_JUMP_SLOT __gmon_start__ 0000000000600b38 R_X86_64_JUMP_SLOT राशि   

तो यह कैसे काम करता है, जब तक लायब्रेरी फ़ाइल मौजूद है और इसमें प्रोग्राम द्वारा संदर्भित प्रतीकों को शामिल किया गया है, गतिशील लिंकर खुश है और जोड़ता है

यदि हम my_global_var को 43 में बदलते हैं, तो लीब के पुनर्निर्माण के लिए, और प्रोग्राम को बिना किसी पुनर्निर्माण के चलाया जा सकता है: >

  $ ./program5 + 2 = 7 और my_global_var = 43   

अगर हम लिप से my_global_var को निकालते हैं, तो प्रतीक गायब हो जाता है, और प्रोग्राम शुरू नहीं किया जा सकता है, क्योंकि गतिशील लिंकर खुश नहीं है:

  $ ./program ./program: symbol lookup त्रुटि: ./program: अपरिभाषित प्रतीक: my_global_var   

अब मुश्किल भाग, हम sum के प्रोटोटाइप को बदलने की कोशिश करते हैं:

  int my_global_var = 43; फ्लोट राशि (फ्लोट ए, फ्लोट बी) {वापसी a + b; }   

हम पुस्तकालय का पुनर्निर्माण करते हैं और प्रोग्राम चलाते हैं:

  $ ./program5 + 2 = 791621423 और my_global_var = 43  < / Pre> 

डायनेमिक लिंकर शिकायत नहीं करता है, लेकिन परिणाम कचरा है क्योंकि प्रोग्राम को int s एक समारोह में पारित किया गया जो अपेक्षित float s।

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

अंतिम समस्या को हल करने के लिए, बड़े पुस्तकालय प्रतीक संस्करण का उपयोग करते हैं यह एक बहुत जटिल विषय है, यहां इसके बारे में विस्तृत लेख है:

Comments

Popular posts from this blog

Java - Error: no suitable method found for add(int, java.lang.String) -

java - JPA TypedQuery: Parameter value element did not match expected type -

c++ - static template member variable has internal linkage but is not defined -