यदि आप सादे C निर्यात चाहते हैं, तो C ++ नहीं C प्रोजेक्ट का उपयोग करें। सी ++ डीएलएल सभी सी ++ आइएमएस (नाम स्थान आदि ...) के लिए नाम-प्रबंध पर भरोसा करते हैं। आप अपने कोड को C / C ++ -> उन्नत के तहत अपनी परियोजना सेटिंग्स में जाकर C के रूप में संकलित कर सकते हैं, एक विकल्प "Compile As" है जो कंपाइलर स्विच / TP और / TC से मेल खाता है।
यदि आप अभी भी C ++ का उपयोग करना चाहते हैं, तो अपने काम के आंतरिक भाग को लिखने के लिए, लेकिन C ++ के बाहर उपयोग के लिए अनवांटेड कुछ फ़ंक्शन निर्यात करें, नीचे दूसरा खंड देखें।
VC ++ में DLL Libs का निर्यात / आयात करना
क्या आप वास्तव में करना चाहते हैं एक हैडर में एक सशर्त मैक्रो को परिभाषित करना है जो आपके DLL प्रोजेक्ट में सभी स्रोत फ़ाइलों में शामिल होगा:
#ifdef LIBRARY_EXPORTS
# define LIBRARY_API __declspec(dllexport)
#else
# define LIBRARY_API __declspec(dllimport)
#endif
फिर एक ऐसे फंक्शन पर जिसे आप एक्सपोर्ट करना चाहते हैं LIBRARY_API
:
LIBRARY_API int GetCoolInteger();
आपके लाइब्रेरी बिल्ड प्रोजेक्ट में LIBRARY_EXPORTS
यह परिभाषित होता है कि यह आपके कार्यों को आपके DLL बिल्ड के लिए निर्यात किया जाएगा।
चूंकि LIBRARY_EXPORTS
DLL का उपभोग करने वाली परियोजना में परिभाषित नहीं किया जाएगा, जब उस परियोजना में आपकी लाइब्रेरी की हेडर फ़ाइल शामिल होती है, जिसके बजाय सभी फ़ंक्शन आयात किए जाएंगे।
यदि आपकी लाइब्रेरी क्रॉस-प्लेटफ़ॉर्म होने वाली है, तो आप LIBRARY_API को विंडोज पर न होने के कारण परिभाषित कर सकते हैं:
#ifdef _WIN32
# ifdef LIBRARY_EXPORTS
# define LIBRARY_API __declspec(dllexport)
# else
# define LIBRARY_API __declspec(dllimport)
# endif
#elif
# define LIBRARY_API
#endif
Dllexport / dllimport का उपयोग करते समय आपको DEF फ़ाइलों का उपयोग करने की आवश्यकता नहीं होती है, यदि आप DEF फ़ाइलों का उपयोग करते हैं तो आपको dllexport / dllimport का उपयोग करने की आवश्यकता नहीं है। दो विधियाँ एक ही कार्य को अलग-अलग तरीके से पूरा करती हैं, मेरा मानना है कि dllexport / dllimport दोनों में से अनुशंसित विधि है।
LoadLibrary / PInvoke के लिए C ++ DLL से असंबद्ध कार्यों का निर्यात करना
यदि आपको LoadLibrary और GetProcAddress का उपयोग करने की आवश्यकता है, या शायद किसी अन्य भाषा (यानी .NET से PInvoke, या Python / R आदि में FFI) का आयात कर रहे हैं, तो आप extern "C"
Cl कंपाइलर को नाम न बताने के लिए बताने के लिए अपने dllexport के साथ इनलाइन का उपयोग कर सकते हैं । और चूंकि हम dllimport के बजाय GetProcAddress का उपयोग कर रहे हैं, हमें ऊपर से ifdef नृत्य करने की आवश्यकता नहीं है, बस एक साधारण dllexport:
कोड:
#define EXTERN_DLL_EXPORT extern "C" __declspec(dllexport)
EXTERN_DLL_EXPORT int getEngineVersion() {
return 1;
}
EXTERN_DLL_EXPORT void registerPlugin(Kernel &K) {
K.getGraphicsServer().addGraphicsDriver(
auto_ptr<GraphicsServer::GraphicsDriver>(new OpenGLGraphicsDriver())
);
}
और यहाँ निर्यात डम्पबिन / निर्यात के साथ कैसा दिखता है:
Dump of file opengl_plugin.dll
File Type: DLL
Section contains the following exports for opengl_plugin.dll
00000000 characteristics
49866068 time date stamp Sun Feb 01 19:54:32 2009
0.00 version
1 ordinal base
2 number of functions
2 number of names
ordinal hint RVA name
1 0 0001110E getEngineVersion = @ILT+265(_getEngineVersion)
2 1 00011028 registerPlugin = @ILT+35(_registerPlugin)
तो यह कोड ठीक काम करता है:
m_hDLL = ::LoadLibrary(T"opengl_plugin.dll");
m_pfnGetEngineVersion = reinterpret_cast<fnGetEngineVersion *>(
::GetProcAddress(m_hDLL, "getEngineVersion")
);
m_pfnRegisterPlugin = reinterpret_cast<fnRegisterPlugin *>(
::GetProcAddress(m_hDLL, "registerPlugin")
);
extern C
सजावट को हटा देगा जो फ़ंक्शन के पैरामीटर प्रकारों का वर्णन करता है, लेकिन सजावट नहीं जो फ़ंक्शन के कॉलिंग सम्मेलन का वर्णन करता है; बी) डीईएफ फ़ाइल में आपको (अघोषित) नाम निर्दिष्ट करने के लिए आवश्यक सभी सजावट को हटाने के लिए ।