2013-05-21 11 views
6

मैं एक सी #/जावा पृष्ठभूमि से आया था, इसलिए मैं एक सी ++ डीएल बनाने के तरीके को समझने की कोशिश कर रहा हूं जो सी # डीएल के समान व्यवहार करता है।सी ++ कक्षा को डीएलएल के रूप में कैसे निर्यात करें?

मैंने __declspec(dllexport) और __declspec(dllimport) के साथ प्रयोग किया है, लेकिन मैंने इसे केवल स्थिर तरीकों पर काम करने में कामयाब रहा है। मुझे यकीन है कि यह मेरी सीमित समझ के कारण है।

मैं सी ++ में कक्षाओं को कैसे निर्यात कर सकता हूं (पूरी तरह से निजी सदस्यों सहित) और संदर्भ के अंत में उन्हें तुरंत चालू करने में सक्षम हूं क्योंकि मैं सी # के साथ होगा? ऑनलाइन संसाधन/ट्यूटोरियल के लिए कुछ पॉइंटर भी ऐसा करेंगे।

मैंने एमएफसी डीएलएल टेम्पलेट का उपयोग शुरू किया, और ईमानदारी से मुझे नहीं पता कि उनमें से 9 0% किसके लिए हैं और मैं CWinApp से क्यों विरासत में हूं। मैंने कक्षा को CCppPracticeLibraryApp के साथ टैग करने का प्रयास किया लेकिन यह अब संकलित नहीं होगा।

// CppPracticeLibrary.h : main header file for the CppPracticeLibrary DLL 
// 


#pragma once 

#ifndef __AFXWIN_H__ 
    #error "include 'stdafx.h' before including this file for PCH" 
#endif 

#include "resource.h"  // main symbols 

#ifdef CCppPracticeLibraryApp_EXPORTS 
#define CCppPracticeLibraryApp_API __declspec(dllexport) 
#else 
#define CCppPracticeLibraryApp_API __declspec(dllimport) 
#endif 

// CCppPracticeLibraryApp 
// See CppPracticeLibrary.cpp for the implementation of this class 
// 

class CCppPracticeLibraryApp : public CWinApp 
{ 
public: 
    CCppPracticeLibraryApp(); 
    static CCppPracticeLibraryApp_API void SayHelloWorld(); 
// Overrides 
public: 
    virtual BOOL InitInstance(); 

    DECLARE_MESSAGE_MAP() 
}; 

परिभाषा फ़ाइल:

//CppPracticeLibrary.cpp: DLL के लिए प्रारंभ दिनचर्या को परिभाषित करता है।

#include "stdafx.h" 
#include "CppPracticeLibrary.h" 

#ifdef _DEBUG 
#define new DEBUG_NEW 
#endif 

#define CCppPracticeLibraryApp_EXPORTS 



BEGIN_MESSAGE_MAP(CCppPracticeLibraryApp, CWinApp) 
END_MESSAGE_MAP() 


// CCppPracticeLibraryApp construction 

CCppPracticeLibraryApp::CCppPracticeLibraryApp() 
{ 
    // TODO: add construction code here, 
    // Place all significant initialization in InitInstance 
} 

void CCppPracticeLibraryApp::SayHelloWorld() 
{ 
    printf("Hello world"); 
} 


// The one and only CCppPracticeLibraryApp object 

CCppPracticeLibraryApp theApp; 


// CCppPracticeLibraryApp initialization 

BOOL CCppPracticeLibraryApp::InitInstance() 
{ 
    CWinApp::InitInstance(); 

    return TRUE; 
} 

क्लाइंट/संदर्भित विधि

// TestConsoleApplication.cpp : Defines the entry point for the console application. 
// 

#include "stdafx.h" 
#include "TestConsoleApplication.h" 
#include "CppPracticeLibrary.h" 

#ifdef _DEBUG 
#define new DEBUG_NEW 
#endif 


// The one and only application object 

CWinApp theApp; 

using namespace std; 

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) 
{ 
    int nRetCode = 0; 

    HMODULE hModule = ::GetModuleHandle(NULL); 

    if (hModule != NULL) 
    { 
     // initialize MFC and print and error on failure 
     if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0)) 
     { 
      // TODO: change error code to suit your needs 
      _tprintf(_T("Fatal Error: MFC initialization failed\n")); 
      nRetCode = 1; 
     } 
     else 
     { 
      // TODO: code your application's behavior here. 
      /*CCppPracticeLibraryApp* testCallingLibrary = new CCppPracticeLibraryApp(); 
      testCallingLibrary->SayHelloWorld();*/ 
      CCppPracticeLibraryApp::SayHelloWorld(); 
     } 
    } 
    else 
    { 
     // TODO: change error code to suit your needs 
     _tprintf(_T("Fatal Error: GetModuleHandle failed\n")); 
     nRetCode = 1; 
    } 

    return nRetCode; 
} 

मैं उपरोक्त कोड में निम्नलिखित लाइनों uncomment करने में सक्षम होना चाहते हैं:

 /*CCppPracticeLibraryApp* testCallingLibrary = new CCppPracticeLibraryApp(); 
     testCallingLibrary->SayHelloWorld();*/ 
+0

कृपया अपना कोड दिखाएं ... –

+0

@ bash.d कोड के साथ अपडेट किया गया। – Alwyn

उत्तर

4

से MSDN

सार्वजनिक डेटा के सदस्यों और एक कक्षा में सदस्य कार्यों के सभी निर्यात करने के लिए कीवर्ड के रूप में इस वर्ग के नाम के बाईं ओर दिखाई देना चाहिए , मान लें कि ऐसा करने के और तरीके हैं, जैसे .DEF -files। एमएसडीएन साइट पर स्पष्टीकरण के माध्यम से पढ़ने के लिए अपना समय लें।

+0

क्या मैं संदर्भ कोड पर 'sixampleExport' कक्षा' नया कर सकता हूं? उस लेख के माध्यम से यह कहता है कि यह केवल 'सार्वजनिक' सदस्यों को ही निर्यात करेगा। क्या इसका मतलब है कि तत्काल वर्ग के पास अभी भी निजी सदस्य तक पहुंच होगी, केवल वे ही पहुंच योग्य नहीं होंगे या वे सभी समय पर आयात नहीं किए जाएंगे? – Alwyn

+2

@Alwyn यह एक वर्ग के सभी सदस्यों को निर्यात करता है जिसमें आंतरिक कंपाइलर जेनरेट कोड और डेटा जैसे वीटेबल, निहित रूप से जेनरेट किए गए सदस्य फ़ंक्शंस, आरटीटीआई इत्यादि शामिल हैं –

+1

यह दृश्यता-दायरे के बारे में है। आप डीएलएल में प्रवेश बिंदु बना रहे हैं, जिसका उपयोग किया जा सकता है इसका मतलब यह है कि आप निजी सदस्यों को इस तरह सार्वजनिक नहीं बना सकते हैं। –

3

आदेश में एक के सभी सदस्यों को निर्यात करने के लिए में कक्षा में आप नीचे की घोषणा में declspec शामिल कर सकते हैं।

class __declspec(dllexport) CExampleExport : public CObject 
{ ... class definition ... }; 

इसके अलावा:

class __declspec(dllexport) ExportedClass 
{ 
    //.... 
}; 
+0

यह भी सही उत्तर है :(यदि मैं केवल आपको सही उत्तर देने के रूप में चिह्नित कर सकता हूं, तो मैं चाहता हूं। लेकिन मैंने +1 दिया। – Alwyn

5

__declspec (dllexport) और __declspec (dllimport) के साथ आप बस एक एपीआई बनाते हैं जिसका उपयोग विधियों या आपके डीएल के सदस्यों को निर्यात करने के लिए किया जा सकता है। इस विधियों को निर्यात करके आप इसे किसी अन्य डीएलएल से एक्सेस कर सकते हैं। आप एक हेडर फ़ाइल बनाने के लिए क्या कर सकते हैं जहां आप अपने निर्यात मैक्रो को परिभाषित करेंगे।

ifdef MYPROJECT_EXPORTS 
     define MYPROJECT_EXPORTS__declspec(dllexport) 
    else 
     define MYPROJECT_EXPORTS__declspec(dllimport) 
    endif 

और जब आप अपने प्रणाली की घोषणा, यदि आप इसे निर्यात करना चाहते हैं, तो आप सिर्फ इस तरह, अपने विधि घोषणा करने से पहले अपने मैक्रो रखना होगा:

MYPROJECT_EXPORTS void myMethod(); 

और यह भी आप अपने जोड़ने के लिए प्रीप्रोसेसर परिभाषाओं में प्रतीक (एमएस विजुअल स्टूडियो में -> परियोजना गुण -> सी/सी ++ -> प्रीप्रोसेसर -> प्रीप्रोसेसर परिभाषाएं

3

आपको इस विषय पर this very interesting article on CodeProject पढ़ना होगा।

ध्यान दें कि यदि आप सीमाओं (MFC कक्षाएं, या एसटीएल कक्षाओं सहित) पर सी ++ वर्गों के साथ एक DLL का निर्माण, अपने DLL ग्राहक ही कुलपति ++ संकलक संस्करण और ही सीआरटी स्वाद का उपयोग करना चाहिए (उदाहरण के लिए बहुभाषी डीएलएल डीबग सीआरटी, मल्टीथ्रेडेड डीएलएल रिलीज सीआरटी, और अन्य "अधिक सूक्ष्म" सेटिंग्स, जैसे _HAS_ITERATOR_DEBUGGING सेटिंग्स) डीएलएल का उपयोग करने वाले EXEs बनाने के लिए।

इसके बजाय, अगर आप DLL से एक शुद्ध सी इंटरफ़ेस निर्यात (लेकिन आप सी ++ अंदर DLL, बस Win32 एपीआई की तरह उपयोग कर सकते हैं), या यदि आप कॉम DLLs का निर्माण, अपने DLL ग्राहकों का उपयोग कर सकते अपने डीएलएल का उपयोग करने के लिए वीसी ++ कंपाइलर (और यहां तक ​​कि विभिन्न सीआरटी) का एक अलग संस्करण।

इसके अलावा, उपर्युक्त लेख "C++ Mature Approach" (यानी एक अमूर्त इंटरफ़ेस का उपयोग करके) के रूप में परिभाषित करता है, इसके अलावा भी ध्यान दें।

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