2012-05-02 10 views
5

से लिंक करें शीर्षक के अनुसार, मैं सी का उपयोग करके डीएलएल बनाने और इसे C++ प्रोजेक्ट से लिंक करने का प्रयास कर रहा हूं। मैंने इंटरनेट पर विभिन्न ट्यूटोरियल पढ़े और उनका पालन किया लेकिन हर बार कुछ गायब है और मुझे समझ में नहीं आता है।सी में एक डीएलएल बनाएं और इसे C++ प्रोजेक्ट

यहाँ मैं क्या किया, कदम से कदम है:

मैं एक नया Win32 परियोजना, तो testlib नाम है, बनाया, जादूगर से, मैं "DLL" और "खाली परियोजना" चुना है।

जोड़ा एक हैडर:

//testlib.h 

#include <stdio.h> 

__declspec(dllexport) void hello(); 

जोड़ा एक स्रोत; के बाद से मैं इसे एक सी स्रोत होना चाहता हूँ मैंने पढ़ा है मैं simplly ग में सीपीपी फ़ाइल का नाम बदलने चाहिए, ताकि

//testlib.c 

#include "testlib.h" 

void hello() { 
    printf("DLL hello() called\n"); 
} 

बिल्ड succeded।

अब मैं किसी अन्य प्रोजेक्ट में अपने उपयोगी डीएल का उपयोग करना चाहता हूं।

फिर: नई परियोजना (testlibUse)। इस बार मैंने "खाली परियोजना" चुना।
एक शीर्ष लेख जोड़ने के लिए कोई ज़रूरत नहीं है, बस एक cpp स्रोत

//main.cpp 
#include <testlib.h> 

int main() { 
    hello(); 
} 

फिर बनाया:

  • मैं फ़ोल्डर है जहाँ गुण में testlib.dll> कुलपति ++ directories-> निष्पादन निर्देशिका है करने के लिए पथ जोड़ा

  • मैं कुलपति ++ directories-> निर्देशिका शामिल करें फ़ोल्डर है जहाँ गुण में testlib.h> है करने के लिए पथ जोड़ा

  • 012,
  • मैं testlib.lib (शामिल विस्तार) गुण में> Linker-> इनपुट-> अतिरिक्त निर्भरता

मैं निर्माण करने की कोशिश करने के लिए पथ जोड़ा है, लेकिन मैं एक लिंकर त्रुटि मिली:

LINK : C:\path\testlibUse\Debug\testlibUse.exe not found or not built by the last incremental link; performing full link
main.obj : error LNK2019: unresolved external symbol "void __cdecl hello(void)" ([email protected]@YAXXZ) referenced in function _main
C:\path\testlibUse\Debug\testlibUse.exe : fatal error LNK1120: 1 unresolved externals

अगर मैं testlib पर वापस जाता हूं, testlib.cpp में वापस नाम बदलें और डीएलएल का पुनर्निर्माण करें, तो मैं testlibUse बनाने में सक्षम हूं लेकिन मुझे रनटाइम पर "dll नहीं मिला" त्रुटि मिलती है।

मैंने "रिलीज" (आवश्यक पथ को बदलने) में दोनों परियोजनाओं की कॉन्फ़िगरेशन को बदलने की कोशिश की, लेकिन कुछ भी नहीं बदला।

लंबी पोस्ट के लिए खेद है, लेकिन मुझे लगता है कि मैंने जो कुछ किया है उसे लिखना आवश्यक था।

कोई सुझाव?

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

उत्तर

9

आप कई समस्याएं हैं:

  1. हेडर फाइल के रूप में निर्यात जब DLL में संकलित किया जा रहा है, लेकिन आयातित कार्यों को चिह्नित करना चाहिए पुस्तकालय उपयोगकर्ता द्वारा संकलित किया जा रहा है।
  2. हेडर फाइल जब सी ++ के रूप में संकलित किया जा रहा यह सुनिश्चित करें कि नाम घायल
  3. नहीं मिलता है DLL अपने निष्पादन के पुस्तकालय खोज पथ पर नहीं है एक extern "C" ब्लॉक में समारोह घोषणाओं लपेट चाहिए, तो यह नहीं पाया जा सकता है चलने के समय पर।

(1) ठीक करने के लिए और (2), इस तरह से अपनी शीर्ष लेख को फिर से लिखने:

#ifdef __cplusplus 
extern "C" { 
#endif 

// Assume this symbol is only defined by your DLL project, so we can either 
// export or import the symbols as appropriate 
#if COMPILING_MY_TEST_DLL 
#define TESTLIB_EXPORT __declspec(dllexport) 
#else 
#define TESTLIB_EXPORT __declspec(dllimport) 
#endif 

TESTLIB_EXPORT void hello(); 
// ... more function declarations, marked with TESTLIB_EXPORT 

#ifdef __cplusplus 
} 
#endif 

ठीक करने के लिए (3), अपने निष्पादन योग्य फ़ाइल को उसी फ़ोल्डर में DLL कॉपी। आपके द्वारा सेट की जा रही "निष्पादन योग्य निर्देशिका" सेटिंग DLL खोज को प्रभावित नहीं करती है - डीएलएल की खोज कैसे की जाती है इसके बारे में विस्तृत विवरण के लिए MSDN देखें। आपके लिए सबसे अच्छा समाधान है कि आप अपने डीएलएल को उस निर्देशिका में कॉपी करें जहां आपकी निष्पादन योग्य फ़ाइल रहती है। आप या तो मैन्युअल रूप से ऐसा कर सकते हैं, या अपने प्रोजेक्ट में पोस्ट-बिल्ड चरण जोड़ सकते हैं जो आपके लिए यह करता है।

1

ऐसा लगता है कि आपको यह सुनिश्चित करने की आवश्यकता है कि संकलक mangle सीपीपी निर्माण में प्रतीक नाम नहीं है। आप testlib में परिभाषा के लिए extern "C" जोड़ने में सक्षम होना चाहिए।ज:

#ifdef __cplusplus 
extern "C" 
#endif 
__declspec(dllexport) void hello(); 
+0

लेकिन मैं क्रम में एक "नहीं मिला DLL" त्रुटि मिलती है ... गुण> कुलपति ++ directories-> निष्पादन निर्देशिका में dll के लिए पथ को जोड़ने के लिए पर्याप्त नहीं था? – Saphrosit

+0

@ सैफ्रोसिट: नहीं, मेरे सबसे अच्छे ज्ञान के लिए, जो ऐप के चलने को प्रभावित नहीं करेगा। उस प्रॉपर्टी पेज पर विवरण पढ़ें; यह परियोजना के निर्माण के दौरान द्विआधारी की खोज को प्रभावित करता है। रनटाइम पर आपको डीएलएल मिलना चाहिए (उदाहरण के लिए, पाथ पर्यावरण चर के माध्यम से)। –

2

आप extern "C" शामिल करना चाहिए:

+0

सफल बनाएं लेकिन मुझे रनटाइम पर "dll नहीं मिला" त्रुटि मिलती है ... गुणों में> DC++ निर्देशिका-> निष्पादन योग्य निर्देशिकाओं में पथ जोड़ने के लिए पर्याप्त नहीं था? – Saphrosit

1

यहां आपके सी हेडर फ़ाइल के लिए एक विधि है जिसे C++ द्वारा शामिल किया जा सकता है। TESTLIB_EXPORTS को केवल अपने DLL प्रीप्रोसेसर सेटिंग्स में सेट करना सुनिश्चित करें। परियोजनाओं में जो इस हेडर को डीएलएल का उपयोग करने के लिए शामिल करते हैं, हेडर निर्यात के बजाय आयात के रूप में कार्यों को घोषित करेगा।

__cplusplus गार्ड संकलक को सी ++ नाम सजावट के बजाय सी नाम सजावट का उपयोग करके अपने कार्यों को आयात करने के लिए बताएगा।

#include <stdio.h> 

#ifdef TESTLIB_EXPORTS 
#define TESTLIB_API __declspec(dllexport) 
#else 
#define TESTLIB_API __declspec(dllimport) 
#endif 

#ifdef __cplusplus 
extern "C" { 
#endif 

TESTLIB_API void hello(); 
/* other prototypes here */ 

#ifdef __cplusplus 
} 
#endif 
बिल्ड सफल
संबंधित मुद्दे