2010-07-14 14 views
5

से जोड़ने में "एकाधिक परिभाषित प्रतीकों" के आसपास कैसे प्राप्त करें मैं एक पुराने सिस्टम का उपयोग कर रहा हूं जिसमें gcc 2.95.3 है, मुझे दो ऑब्जेक्ट्स में लिंक करना होगा, हालांकि उनमें से प्रत्येक के पास कुछ भी नहीं है, उनमें से प्रत्येक के पास इसी तरह नामित विधियों। मैं उनमें से किसी का नाम नहीं बदल सकता, लेकिन मुझे उम्मीद है कि उन्हें बनाने का एक तरीका है क्योंकि लिंकर शिकायत नहीं करता है। जिन तरीकों से यह शिकायत कर रही है वे आंतरिक रूप से ऑब्जेक्ट के भीतर कक्षाओं द्वारा बुलाए जाते हैं। मैं क्या कर सकता हूँ?जीसीसी

उत्तर

9

आप एक पूरा जीएनयू toolchain है, तो आप objcopy, इस तरह का उपयोग कर अपने समस्या को हल करने के लिए सक्षम है (अगर मैं आपकी समस्या को समझ लिया है सही ढंग से) किया जाना चाहिए: foo

यहाँ दो बहुत समान वस्तुओं रहे हैं, " "और" बार ", जो दोनों के एक प्रतीक clash बुलाया निर्यात - जो आंतरिक रूप से प्रयोग किया जाता है, लेकिन वास्तव में सब पर निर्यात किए जाने की जरूरत नहीं है:

$ cat foo.c 
#include <stdio.h> 
void clash(char *s) { printf("foo: %s\n", s); } 
void foo(char *s) { clash(s); } 
$ 

और

$ cat bar.c 
#include <stdio.h> 
void clash(char *s) { printf("bar: %s\n", s); } 
void bar(char *s) { clash(s); } 
$ 

और यहाँ मुख्य कोड है, जो दोनों का उपयोग करना चाहता है:

$ cat main.c 
extern void foo(char *s); 
extern void bar(char *s); 

int main(void) 
{ 
    foo("Hello"); 
    bar("world"); 
    return 0; 
} 
$ 

उन्हें एक साथ लिंक करना काम नहीं करता है:

$ gcc -Wall -c foo.c 
$ gcc -Wall -c bar.c 
$ gcc -Wall -c main.c 
$ gcc -o test main.o foo.o bar.o 
bar.o: In function `clash': 
bar.c:(.text+0x0): multiple definition of `clash' 
foo.o:foo.c:(.text+0x0): first defined here 
collect2: ld returned 1 exit status 
$ 

तो, objcopy का उपयोग एक में clash की दृश्यता को बदलने के लिए (या दोनों, आप वस्तुओं की तरह अगर):

$ objcopy --localize-symbol=clash bar.o bar2.o 
$ 

अब आप संशोधित वस्तु के साथ सफलतापूर्वक लिंक कर सकते हैं - और इस कार्यक्रम के रूप में व्यवहार! यह होना चाहिए:

$ gcc -o test main.o foo.o bar2.o 
$ ./test 
foo: Hello 
bar: world 
$ 
+1

फॉर्म ऑब्जेक्ट करने से पहले मैं स्थानीय निर्दिष्ट कैसे कर सकता हूं? आदर्श रूप से कोड में, लेकिन ऑब्जेक्ट संकलन के हिस्से के रूप में भी हो सकता है? – CptanPanic

+2

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