2009-07-01 22 views
21

का उपयोग करके लिंक नहीं कर रहा है मेरे पास एक सी-लाइब्रेरी है जिसका मैं जीसीसी में उपयोग करता हूं। पुस्तकालय में एक्सटेंशन है। Lib लेकिन हमेशा एक स्थिर पुस्तकालय के रूप में जुड़ा हुआ है। यदि मैं एक प्रोग्राम लिखता हूं जो लाइब्रेरी को सी-कोड के रूप में उपयोग करता है, तो सब कुछ ठीक है। अगर मैं फ़ाइल को .cpp में बदलता हूं (सरल सामग्री जो सी/सी ++ दोनों में काम करता है) मुझे अपरिभाषित संदर्भ मिलता है। ये सरल छोटे कार्यक्रम हैं जिन्हें मैं परीक्षण उद्देश्यों के लिए लिखता हूं ताकि कोई फैंसी सामान न हो। मैं उपयोग कर संकलन:सी-लाइब्रेरी जीसीसी/जी ++

gcc -g -Wall -I <path to custom headers> -o program main.c customlibrary.lib -lm -lpthread 

उपर्युक्त काम एक आकर्षण की तरह काम करता है। हालांकि: customlibrary.lib में किसी भी कार्य करने के लिए अपरिभाषित संदर्भ में

g++ -g -Wall -I <path to custom headers> -o program main.cpp customlibrary.lib -lm -lpthread 

या

gcc -g -Wall -I <path to custom headers> -o program main.cpp customlibrary.lib -lm -lpthread -lstdc++ 

का परिणाम है। मैंने customlibrary.a नामक एक प्रतीकात्मक लिंक बनाने की कोशिश की लेकिन कोई भाग्य नहीं।

जी ++ मेरी लाइब्रेरी को क्यों पहचान नहीं पाएगा। दुर्भाग्यवश मेरे पास पुस्तकालयों के स्रोत कोड तक कोई पहुंच नहीं है लेकिन सी-lib को C++ से जोड़ने से कोई समस्या नहीं होनी चाहिए?

उत्तर

37

आपकी लाइब्रेरी में एक एपीआई प्रतीत होता है जो मानता है कि इसे सी से नहीं कहा जाएगा, सी ++ नहीं। यह महत्वपूर्ण है क्योंकि सी ++ प्रभावी रूप से आवश्यक है कि लाइब्रेरी से निर्यात किए गए प्रतीकों में फ़ंक्शन नाम की तुलना में उनमें अधिक जानकारी हो। यह कार्यों को "नाम mangling" द्वारा संभाला जाता है।

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

एक संभावना आसान जवाब इस परीक्षण करने के लिए यह करने के लिए है:

extern "C" { 
#include "customlibrary.h" 
} 
अपने बजाय main.cpp बस सीधे customlibrary.h सहित

#ifdef __cplusplus 
extern "C" { 
#endif 

और तल के पास निम्न:

हैडर ही दोनों भाषाओं में काम करते हैं और सही ढंग से करने के लिए सी ++ सी-तरह के रूप में अपने कार्यों की घोषणा करने के लिए, हेडर फाइल के शीर्ष के निकट निम्नलिखित डाल:

#ifdef __cplusplus 
} 
#endif 
+1

प्रतीक '__cplusplus' दो अंडरस्कोर है:

// myfile.cpp extern "C" int libfun(); // C function in your library 

या एक पूरे हेडर फाइल के लिए यह करना: सामान्य तरीके से इस दौर संकलक कि कुछ कार्यों की जरूरत है सी लिंकेज बताने के लिए है प्रासंगिक मानकों से। – RBerteig

2

अपने हेडर फाइल सामान्य

#ifdef __cplusplus 
extern "C" { 
#endif 

// ... 

#ifdef __cplusplus 
} /* extern "C" */ 
#endif 

है ली देने के लिए करता है ब्रैरी फ़ंक्शंस सी लिंकेज स्पष्ट रूप से।

.cpp फ़ाइलों को सी ++ लिंकेज के साथ संकलित किया गया है यानी डिफ़ॉल्ट रूप से नाम मैंगलिंग।

4

सी ++ कंपाइलर नाम-मैंगलिंग के रूप में जाना जाता है - आपके कोड में दिखाई देने वाले नाम वही नहीं हैं जैसे आपका लिंकर देखता है। के रूप में परिभाषित,

// myfile.cpp 
extern "C" { 
    #include "mylibdefs.h"  // defs for your C library functions 
}