2009-12-01 14 views
11

के बीच एक पुल बनाने के लिए प्रबंधित किया गया है, मैं थोड़ा सी जंगली हूं, असल में वास्तव में मेरे सी ++ के साथ जंगली हूं। कॉलेज के फ्रेशमैन वर्ष के बाद से इसे छुआ नहीं है, इसलिए यह थोड़ी देर हो गया है।प्रबंधित सी ++ सी # और सी ++

वैसे भी, मैं अधिकांश लोगों के विपरीत होने के विपरीत कर रहा हूं। सी ++ से सी # कोड कॉलिंग। मैंने कुछ शोध ऑनलाइन किया है और ऐसा लगता है कि मुझे पुल बनाने के लिए कुछ प्रबंधित सी ++ बनाना होगा। __declspec (dllexport) का उपयोग करें और फिर उस से एक डीएलएल बनाएँ और पूरी चीज को एक रैपर के रूप में उपयोग करें।

लेकिन मेरी समस्या यह है - मुझे वास्तव में उदाहरण खोजने में कठिनाई हो रही है। मुझे कुछ बुनियादी चीजें मिलीं जहां कोई सी # संस्करण का उपयोग स्ट्रिंग.ToUpper() पर करना चाहता था लेकिन यह बहुत ही बुनियादी था और केवल एक छोटा कोड स्निपेट था।

किसी के पास कोई विचार है कि मैं कुछ और ठोस के लिए कहां देख सकता हूं? नोट, मैं COM का उपयोग नहीं करना चाहता। लक्ष्य सी # कोड को बिल्कुल छूना नहीं है।

+0

अप्रत्याशित सी/सी ++ में इंटरफ़ेस का खुलासा करना कितना जटिल है? – CuppM

+0

इस लिंक को एक समान प्रश्न/उत्तर के लिए देखें: http://stackoverflow.com/questions/13293888/how-to-call-ac-sharp-library-from-native-c-using-c-cli-and-ijw । – amalgamate

उत्तर

11

जबकि LAIN मुझे एक उदाहरण लिखने के लिए हरा, मैं इसे किसी भी तरह सिर्फ मामले में पोस्ट करेंगे ...

अपनी खुद की लाइब्रेरी का उपयोग करने के लिए एक आवरण लिखने की प्रक्रिया मानक नेट पुस्तकालयों में से एक को एक्सेस करने के समान है।

उदाहरण सी एक परियोजना CsharpProject बुलाया में # वर्ग कोड:

using System; 

namespace CsharpProject { 
    public class CsharpClass { 
     public string Name { get; set; } 
     public int Value { get; set; } 

     public string GetDisplayString() { 
      return string.Format("{0}: {1}", this.Name, this.Value); 
     } 
    } 
} 

आप प्रबंधित सी ++ वर्ग पुस्तकालय परियोजना बनाने (उदाहरण के CsharpWrapper है) और यह करने के लिए एक संदर्भ के रूप में अपनी सी # परियोजना जोड़ना होगा। आंतरिक उपयोग के लिए और संदर्भ प्रोजेक्ट में समान हेडर फ़ाइल का उपयोग करने के लिए, आपको सही declspec का उपयोग करने का एक तरीका चाहिए। यह एक प्रीप्रोसेसर निर्देश (CSHARPWRAPPER_EXPORTS इस मामले में) को परिभाषित करके और #ifdef का उपयोग करके हेडर फ़ाइल में अपने सी/सी ++ इंटरफेस में निर्यात मैक्रो सेट करने के लिए किया जा सकता है। अप्रबंधित इंटरफेस हेडर फ़ाइल में अप्रबंधित सामान होना चाहिए (या इसे प्रीप्रोसेसर द्वारा फ़िल्टर किया गया है)।

अप्रबंधित सी ++ इंटरफ़ेस हैडर फ़ाइल (CppInterface।एच):

#pragma once 

#include <string> 

// Sets the interface function's decoration as export or import 
#ifdef CSHARPWRAPPER_EXPORTS 
#define EXPORT_SPEC __declspec(dllexport) 
#else 
#define EXPORT_SPEC __declspec(dllimport) 
#endif 

// Unmanaged interface functions must use all unmanaged types 
EXPORT_SPEC std::string GetDisplayString(const char * pName, int iValue); 

फिर आप अपनी प्रबंधित लाइब्रेरी फ़ाइलों में शामिल करने में सक्षम होने के लिए एक आंतरिक शीर्षलेख फ़ाइल बना सकते हैं। यह using namespace कथन जोड़ देगा और आपको आवश्यक सहायक कार्यों को शामिल कर सकते हैं।

प्रबंधित सी ++ इंटरफ़ेस हैडर फ़ाइल (CsharpInterface.h):

#pragma once 

#include <string> 

// .Net System Namespaces 
using namespace System; 
using namespace System::Runtime::InteropServices; 

// C# Projects 
using namespace CsharpProject; 


////////////////////////////////////////////////// 
// String Conversion Functions 

inline 
String^ToManagedString(const char * pString) { 
return Marshal::PtrToStringAnsi(IntPtr((char *) pString)); 
} 

inline 
const std::string ToStdString(String^strString) { 
IntPtr ptrString = IntPtr::Zero; 
std::string strStdString; 
try { 
    ptrString = Marshal::StringToHGlobalAnsi(strString); 
    strStdString = (char *) ptrString.ToPointer(); 
} 
finally { 
    if (ptrString != IntPtr::Zero) { 
    Marshal::FreeHGlobal(ptrString); 
    } 
} 
return strStdString; 
} 

तो फिर तुम सिर्फ अपने इंटरफेस कोड कि रैपिंग करता लिखें।

प्रबंधित सी ++ इंटरफ़ेस स्रोत फ़ाइल (फ़ाइलें CppInterface.cpp):

#include "CppInterface.h" 
#include "CsharpInterface.h" 

std::string GetDisplayString(const char * pName, int iValue) { 
CsharpClass^oCsharpObject = gcnew CsharpClass(); 

oCsharpObject->Name = ToManagedString(pName); 
oCsharpObject->Value = iValue; 

return ToStdString(oCsharpObject->GetDisplayString()); 
} 

तो बस अपने अप्रबंधित परियोजना में अप्रबंधित हैडर, जब जोड़ने लिंकर उत्पन्न उदारीकरण फ़ाइल का उपयोग करने बताओ, और सुनिश्चित करें कि शामिल नेट और रैपर डीएलएल आपके अप्रबंधित एप्लिकेशन के समान फ़ोल्डर में हैं।

#include <stdlib.h> 

// Include the wrapper header 
#include "CppInterface.h" 

void main() { 
// Call the unmanaged wrapper function 
std::string strDisplayString = GetDisplayString("Test", 123); 

// Do something with it 
printf("%s\n", strDisplayString.c_str()); 
} 
+0

आपने कुछ और चीजों को समझाया - इच्छा है कि मैं दोनों उत्तरों का चयन कर सकता था। धन्यवाद! –

+0

स्ट्रिंग्स एक अच्छा उदाहरण हैं क्योंकि रूपांतरण कार्यों को आवश्यकतानुसार एक स्ट्रिंग को मार्शल से प्रबंधित करने की आवश्यकता होती है (जो आमतौर पर अधिकतर इंटरऑप में बहुत जल्द होता है!) – Iain

+0

"ऐसी कोई फ़ाइल या निर्देशिका नहीं" के लिए, आपको या तो: 1) अप्रबंधित ऐप में 'CppInterface.h' जोड़ें। अगर यह सभी परियोजनाएं एक ही स्थान/भंडार में रहती हैं तो मैं ऐसा नहीं करूंगा। जैसा कि आपके पास बनाए रखने के लिए डुप्लिकेट फ़ाइलें हैं। 2) अप्रबंधित ऐप के संकलन के तहत रैपर प्रोजेक्ट की फ़ाइलों में पथ जोड़ें फ़ोल्डर शामिल करें। विजुअल स्टूडियो के लिए, प्रोजेक्ट पर राइट क्लिक करें और "Properties" चुनें। फिर "कॉन्फ़िगरेशन गुण" के अंतर्गत -> "सी/सी ++" -> "सामान्य" -> "अतिरिक्त शामिल निर्देशिकाएं" 'CppInterface.h' के स्थान पर पथ जोड़ें। – CuppM

10

दृश्य स्टूडियो में एक नया सी ++/सीएलआई प्रोजेक्ट बनाएं और अपने सी # डीएल में एक संदर्भ जोड़ें। मान लें कि हम एक सी # dll में इस वर्ग के साथ DotNetLib.dll कहा जाता है:

namespace DotNetLib 
{ 
    public class Calc 
    { 
     public int Add(int a, int b) 
     { 
      return a + b; 
     } 
    } 
} 

अब ++/CLI परियोजना अपने सेल्सियस के लिए एक CLR सी ++ वर्ग जोड़ें:

// TestCPlusPlus.h 

#pragma once 

using namespace System; 
using namespace DotNetLib; 

namespace TestCPlusPlus { 

    public ref class ManagedCPlusPlus 
    { 
    public: 
     int Add(int a, int b) 
     { 
      Calc^ c = gcnew Calc(); 
      int result = c->Add(a, b); 
      return result; 
     } 
    }; 
} 

यह सी से सी # फोन करेगा ++।

अब अगर जरूरत आप अपने C++/CLI परियोजना जो CLR सी ++ वर्ग के लिए बात कर सकते हैं करने के लिए एक देशी सी ++ वर्ग जोड़ सकते हैं:

// Native.h 
#pragma once 

class Native 
{ 
public: 
    Native(void); 
    int Add(int a, int b); 
    ~Native(void); 
}; 

और:

// Native.cpp 
#include "StdAfx.h" 
#include "Native.h" 
#include "TestCPlusPlus.h" 

Native::Native(void) 
{ 
} 

Native::~Native(void) 
{ 
} 

int Native::Add(int a, int b) 
{ 
    TestCPlusPlus::ManagedCPlusPlus^ c = gcnew TestCPlusPlus::ManagedCPlusPlus(); 
    return c->Add(a, b); 
} 

आप में सक्षम होना चाहिए किसी अन्य मूल सी ++ डीएल के सामान्य के रूप में मूल वर्ग को कॉल करें।

ध्यान दें कि प्रबंधित सी ++ अलग है और सी ++/सीएलआई द्वारा इसे आगे बढ़ाया गया है। विकिपीडिया यह सबसे अच्छा बताते हैं:

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

  • कोई संबंधित समस्या नहीं^_^