2014-10-15 5 views
5

मेरे पास एक बड़ा, मिश्रित सी/फोरट्रान, कोड बेस है, जो वर्तमान में विंडोज़ पर इंटेल टूल्स का उपयोग करके संकलित है। मुझे लिनक्स पर जीएनयू टूल्स को बंदरगाह करने के लिए कहा गया है। यादृच्छिक रूप से कम या ज्यादा, मैंने संस्करण 4.8 चुना है।जीएनयू फोरट्रान और सी इंटरऑपरेबिलिटी

कहाँ एक सी समारोह फोरट्रान से कहा जाता है, अंतर अक्सर इस तरह दिखता है:

// C code: 
void PRINTSTR(char *str, size_t len) { 
    for(int ii = 0; ii < len; ii++) { 
     putchar(str[ii]); 
    } 
    putchar('\n'); 
} 

!Fortran code: 
program test 
implicit none 
call printstr("Hello, world.") 
end 

इंटेल फोरट्रान संकलक हमेशा अपर-केस प्रतीकों उत्पन्न करता है, तो यह ठीक काम करता है। लेकिन जीएनयू फोरट्रान कंपाइलर हमेशा कम-केस प्रतीकों उत्पन्न करता है और इसलिए एक लिंकर त्रुटि होती है।

जीएनयू फोरट्रान कंपाइलर का उपयोग -fcase-upper नामक एक विकल्प होता था जिसने इसे ऊपरी-केस प्रतीकों को उत्पन्न किया, लेकिन ऐसा लगता है कि यह हर किसी के लिए बहुत विन्यास योग्य था और इसे हटा दिया गया है (मुझे बिल्कुल यकीन नहीं है)।

यह ISO_C_BINDING सुविधा का उपयोग करने के संकलक मजबूर करने के लिए एक केस-संवेदी नाम उत्पन्न करने के लिए संभव है:

program test 
interface 
subroutine printstr(str) bind(C, name='PRINTSTR') 
character :: str(*) 
end subroutine 
end interface 

call printstr("Hello, world.") 
end 

यह लिंकर त्रुटि को हल करता है, लेकिन यह परिवर्तन कैसे स्ट्रिंग पैरामीटर नियंत्रित किया जाता है; लंबाई पैरामीटर अब प्रदान नहीं किया गया है। इसलिए इस विधि का उपयोग करने के लिए, मुझे केवल इस फ़ंक्शन पर काम करने वाले प्रत्येक फ़ंक्शन के लिए इंटरफ़ेस परिभाषाएं नहीं जोड़नी होंगी, लेकिन मुझे यह भी बदलना होगा कि प्रत्येक कॉल में स्ट्रिंग को इस तरह के फ़ंक्शन पर कैसे प्रबंधित किया जाए, यह सुनिश्चित कर लें कि सभी तार शून्य समाप्त हो गए हैं।

मैं इस तरह के सभी कार्यों को कम-मामला बना सकता हूं, लेकिन निश्चित रूप से इंटेल कंपाइलर अभी भी ऊपरी-केस प्रतीकों को उत्पन्न करता है, जिससे मौजूदा निर्माण टूट जाएगा।

चूंकि ~ 2,000 ऐसे फ़ंक्शन हैं, जो कि काम की एक अनावश्यक राशि प्रतीत होती है। तो, मेरा सवाल यह है: मैं फ़ंक्शन कॉल सेमेन्टिक्स को बदले बिना और इंटेल कंपाइलर्स का उपयोग करके मौजूदा बिल्ड को तोड़ने के बिना लिंक त्रुटियों को कैसे हल कर सकता हूं?

+0

मुझे डर है कि एक नहीं बल्कि बड़ी समस्या आप करने जा रहे हैं कि इंटेल, एक 'size_t' के रूप में लंबाई गुजरता है जबकि GFortran' int' का उपयोग करता है हूँ। यह 32-बिट पर ठीक है, लेकिन 64-बिट सिस्टम पर एक बार में एक से अधिक स्ट्रिंग पास करने पर बहुत ही टूट जाता है, और यह लिंकर द्वारा भी पकड़ा नहीं जाता है। –

+0

मुझे लगता है, पूरी तरह से शुभकामनाएं से, मैं उस से दूर हो जाता हूं। इंटेल बिल्ड 32-बिट है। – Tom

+0

मुझे लगता है कि (संभवतः) कंपाइलर जिसमें '-फेस-अपर' था, जी 5 9 था, जीएफओटरन नहीं (जो अब आधिकारिक जीएनयू फोरट्रान कंपाइलर है)। AFAIK g95 अभी भी विकसित है, हालांकि GFortran की तुलना में धीमी गति से, लेकिन यदि आपका कोडबेस शुद्ध F77/F95 है और अत्याधुनिक F2003/F2008 सुविधाओं का उपयोग नहीं करता है, तो यह देखने लायक हो सकता है? –

उत्तर

2

लिंकर त्रुटि को हल करने के लिए आप इसे अन्य तरीकों से कर सकते हैं। डिफ़ॉल्ट जीएनयू फोरट्रान विकल्प से मेल खाने के लिए बाहरी नामों को लोअरकेस में बदलने के लिए इंटेल कंपाइलर विकल्प names का उपयोग करें। और में नाम परिवर्तित भी लोअरकेस:

void printstr(char *str, size_t len) {...} 

व्यक्तिगत तौर पर मैं -funderscoring का उपयोग कर की सिफारिश करेंगे और इंटेल के /assume:underscore कि अंतर के लिए हैं कार्यों भेद करने के लिए।

// C code: 
void printstr_(char *str, size_t len) {...} 

!Fortran code: 
program test 
implicit none 
call printstr("Hello, world.") 
end 
संबंधित मुद्दे