pimpl idiom आमतौर पर आदेश ABI संगतता को तोड़ने और सभी कोड है कि पुस्तकालय पर निर्भर करता है पुन: संयोजित किए बिना गतिशील रूप से जुड़ा हुआ पुस्तकालयों में कोड को बदलने की अनुमति के लिए प्रयोग किया जाता है।एक निजी सदस्य परिवर्तनीय ब्रेक सी ++ एबीआई संगतता कैसे जोड़ता है?
explanations में से अधिकांश का उल्लेख है कि एक नया निजी सदस्य परिवर्तक कक्षा में सार्वजनिक और निजी सदस्यों के ऑफसेट को बदलता है। मेरे लिए उसका मतलब बनता है। जो मुझे समझ में नहीं आता है यह है कि अभ्यास में यह वास्तव में निर्भर पुस्तकालयों को तोड़ देता है।
मैं ELF फ़ाइलें और कैसे गतिशील जोड़ने वास्तव में काम करता है पर पढ़ने का एक बहुत कुछ किया है, लेकिन मैं अभी भी नहीं दिख रहा है कि कैसे साझा lib में कक्षा आकार बदलने चीजें टूट जाएगा।
उदा।
[email protected]:~/pimpl$ objdump -d -j .text a.out
08048874 <main>:
...
8048891: e8 b2 fe ff ff call 8048748 <[email protected]>
some_method
करने के लिए कॉल प्रक्रियात्मक लिंकेज टेबल (PLT) का उपयोग करता है:: यहाँ एक परीक्षण आवेदन (a.out) मैं ने लिखा है कि एक परीक्षण साझा लाइब्रेरी (libInterface.so) से कोड (Interface::some_method
) का उपयोग करता है
[email protected]:~/pimpl$ objdump -d -j .plt a.out
08048748 <[email protected]>:
8048748: ff 25 1c a0 04 08 jmp *0x804a01c
804874e: 68 38 00 00 00 push $0x38
8048753: e9 70 ff ff ff jmp 80486c8 <_init+0x30>
जो बाद में वैश्विक ऑफसेट तालिका (GOT) जहां पता 0x804a01c निहित है को जाता है:
[email protected]:~/pimpl$ readelf -x 24 a.out
Hex dump of section '.got.plt':
0x08049ff4 089f0408 00000000 00000000 de860408 ................
0x0804a004 ee860408 fe860408 0e870408 1e870408 ................
0x0804a014 2e870408 3e870408 4e870408 5e870408 ....>...N...^...
0x0804a024 6e870408 7e870408 8e870408 9e870408 n...~...........
0x0804a034 ae870408 ....
और फिर यहीं गतिशील लिंकर wo libInterface.so में Interface::some_method
पाता है और GOT में अपने कोड some_method
के बाद कॉल पर इतना लोड करता है अपना जादू rks और सभी LD_LIBRARY_PATH में साझा libs में निहित प्रतीकों के माध्यम से लग रहा है,, GOT में कोड वास्तव में से साझा कोड खंड है पुस्तकालय।
या उन पंक्तियों के साथ कुछ।
लेकिन ऊपर दिए गए, मैं अभी भी समझ में नहीं आता कि कैसे साझा लिब के वर्ग के आकार या उसके विधि ऑफसेट खेलने में यहाँ आते हैं। जहां तक मैं कह सकता हूं, ऊपर दिए गए कदम कक्षा के आकार के लिए अज्ञेयवादी हैं। ऐसा लगता है कि लाइब्रेरी में विधि के नाम का प्रतीक केवल एक .out में शामिल है। क्लास आकार में किसी भी बदलाव को रनटाइम पर हल किया जाना चाहिए जब लिंकर कोड को GOT में लोड करता है, नहीं?
मुझे यहां क्या याद आ रही है?
अहा! समझ गया। दरअसल, इंटरफेस के सीटीआर को बुलाए जाने से पहले डिस्सेप्लिब्स में थोड़ा और आगे देखकर, मैं ऑब्जेक्ट के लिए स्पेस आवंटित कर सकता हूं (इस मामले में 4bytes)। – adg