2009-09-23 9 views
25

मैं एक डीएलएल बनाने की कोशिश कर रहा हूं जो "GetName" नामक फ़ंक्शन को निर्यात करता है। मैं चाहता हूं कि अन्य कोड उलझन वाले फ़ंक्शन नाम को जानने के बिना इस फ़ंक्शन को कॉल करने में सक्षम हों।मैं अपने डीएलएल के निर्यात किए गए फ़ंक्शन के नाम-उलझन को कैसे रोकूं?

मेरे हेडर फाइल इस तरह दिखता है:

#ifdef __cplusplus 
#define EXPORT extern "C" __declspec (dllexport) 
#else 
#define EXPORT __declspec (dllexport) 
#endif 

EXPORT TCHAR * CALLBACK GetName(); 

मेरे कोड इस तरह दिखता है:

#include <windows.h> 
#include "PluginOne.h" 

int WINAPI DllMain (HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved) 
{ 
    return TRUE ; 
} 

EXPORT TCHAR * CALLBACK GetName() 
{ 
    return TEXT("Test Name"); 
} 

जब मैं निर्माण, DLL अभी भी नाम के साथ समारोह का निर्यात करता है: "_GetName @ 0" ।

मैं क्या गलत कर रहा हूं?

उत्तर

21

छोटे सुधार - सफलता के लिए clinet

extern "C" 

द्वारा नाम को हल करने आयात पर ही निर्यात के पक्ष में के रूप में होना चाहिए।

बाहरी "सी" से proc का नाम कम हो जाएगा: "_GetName"।

अधिक से अधिक आप .def फ़ाइल

+0

अरे शांत यह वास्तव में मैं लगभग क्या जरूरत है। अब क्या होगा यदि मैं इसे दूसरी तरफ चाहता हूं? मेरे पास सी फ़ंक्शन है, सी ++ सदस्य फ़ंक्शन (vtable, कॉलिंग सम्मेलन सभी को पूरा करने के लिए पूरी तरह से ठीक है), लेकिन संकलक के आंकड़े इसका नाम उलझन में होना चाहिए। – Pyjong

+0

हां, सी और सी ++ अलग-अलग नाम सजावट नियमों का उपयोग करते हैं। जो कुछ आप पूछ रहे हैं उसे करने के लिए आपको रैपर बनाने की आवश्यकता है जो सी ++ वर्ग सदस्य – Dewfy

+0

से सी फ़ंक्शन का आह्वान करेगा। एडीईएफ फ़ाइल नाम मैंगलिंग को अक्षम करने का एकमात्र तरीका है। 'बाहरी "सी" 'अभी भी नाम सजावट का उपयोग करेगा, सिर्फ सी ++ की आवश्यकता के रूप में वर्बोज़ के रूप में नहीं। – IInspectable

9

यह एक __stdcall सम्मेलन के साथ एक DLL निर्यात के लिए सामान्य है में की धारा निर्यात मदद से किसी भी नाम के लिए मजबूर कर सकते हैं। @Nindicates the number of bytes that the function takes in its arguments - आपके मामले में, शून्य।

ध्यान दें कि the MSDN page on Exporting from a DLL विशेष रूप से "__stdcall कॉलिंग सम्मेलन का उपयोग" करने के लिए कहता है "फ़ंक्शन की परिभाषा में कीवर्ड __declspec (dllexport)" का उपयोग करते समय। - सी में है

extern "C" int MyFunc(int param); 

और

int MyFunc(int param); 

दो घोषणाओं जो विभिन्न आंतरिक नामकरण का उपयोग करता है, पहला है:

+1

जैसा कि उल्लेख किया गया है [http://stackoverflow.com/questions/2804893/c-dll-export-decorated-mangled-names), '__stdcall' के मैंगलिंग को दूर करने का एकमात्र तरीका उपयोग करना है: 'pragma टिप्पणी (लिंकर, "/ निर्यात: कुछ समारोह = _SomeFunction @@@ 23mangledstuff # @@@@") ' – Pierre

+0

आपका पहला लिंक टूटा हुआ है और दूसरे अंक –

-1
+1

खराब विचार डाउनलोड करने के लिए; हालांकि यह मंगल को हटा सकता है, यह आयात/निर्यात जोड़ी को असंगत बनाने, कॉलिंग सम्मेलन में भी बदलाव करता है। डीएलएल पर सीडीसीएल का उपयोग करना एक बेहतर विचार आईएमओ है। – vaxquis

4

सही जवाब निम्नलिखित है स्टाइल, दूसरा - सी ++ शैली में।

निर्माण उपकरण के लिए आवश्यक आंतरिक नामकरण, यह निर्धारित करने के लिए कि कौन से तर्क फ़ंक्शन प्राप्त होते हैं, किस प्रकार का रिटर्न इत्यादि, क्योंकि सी ++ अधिक जटिल है (ओओपी, अधिभारित, वर्चुअल फ़ंक्शन इत्यादि) - यह अधिक जटिल नामकरण का उपयोग करता है। कॉलिंग सम्मेलन सी और सी ++ दोनों अर्थों को भी प्रभावित करता है।

नामकरण की ये शैलियों को उसी तरह __declspec (dllexport) का उपयोग करते समय लागू किया जाता है।

अगर आप, निर्यात दिनचर्या का नाम mangling छोड़ एक मॉड्यूल परिभाषा फ़ाइल, प्रकार उस में अपनी परियोजना में जोड़ना चाहते हैं (इस मामले में आप dllexport declspec करने की आवश्यकता नहीं):

LIBRARY mylib 
EXPORTS 
    MyFunc 

इस स्पष्ट छोड़ जाएगा नाम सजावट (नीचे नमूने)।

_MyFunc (c style, __cdecl) 
[email protected] (c style, __stdcall) 
[email protected]@[email protected] (c++ style, __cdecl) 
[email protected]@[email protected] (c++ style, __stdcall) 
0

आप नाम-मैंगलिंग अक्षम करने के लिए "-Wl, - kill-at" लिंकर स्विच का उपयोग कर सकते हैं।

उदाहरण के लिए, कोड :: ब्लाकों में, कस्टम लिंकर सेटिंग्स में, जोड़ें: -Wl, - मारने-पर

संबंधित मुद्दे

 संबंधित मुद्दे