2010-02-06 13 views
62

मेरे पास सी ++ में लागू एक वर्ग है जो कार्यक्रम की अंकगणितीय गणना के लिए जिम्मेदार है, और WPF का उपयोग कर एक इंटरफ़ेस है। मैं सी # के साथ इनपुट को संसाधित करता हूं लेकिन फिर मैं अपनी सी ++ कक्षा का उपयोग कैसे कर सकता हूं?मैं सी #+/सीएलआई को सी # से कैसे कॉल करूं?

मैं इसके साथ बातचीत करने के लिए एक प्रबंधित सी ++ आवरण वर्ग बनाने के बारे में कुछ टिप्पणियां देखा है, लेकिन मैं कहाँ शुरू करने के लिए पता नहीं है। न ही मुझे पता है कि मैं इसे अन्य सभी कोड के साथ संकलित करने के लिए कैसे जाऊंगा। मैं वास्तव में इस पर एक ट्यूटोरियल नहीं ढूंढ सकता, और प्रबंधित सी ++ पर Google शो की सामग्री वास्तव में उपयोगी नहीं लगती है।

मेरी मदद करने के लिए वहां कुछ भी है? यह मेरे लिए अनुचित प्रतीत नहीं होता है।

संपादित करें कोशिश की गई m3rLinEz समाधान लेकिन यह मुझे एक BadImageFormatException दे रहा है, मुझे लगता है कि ऐसा इसलिए है क्योंकि डीएलएल उत्पन्न नहीं होता है। मैंने सबकुछ किया जैसा कि बताया गया था, क्या हुआ। कोई विचार?

+0

यहां एक सभ्य ट्यूटोरियल है: http://www.codeproject.com/KB/mcpp/quickcppcli.aspx#A8 –

+1

मैं समझता हूं कि नेटिस सी ++ सी #/डब्ल्यूपीएफ से तेज़ी से चलता है, लेकिन सीएलआई लिखने का ओवरहेड क्या है अपने मूल सी ++ के आसपास रैपर? क्या यह सब काम वास्तव में इसके लायक है? क्या सी ++ सीआईआई में कोड को सी ++ में बस पोर्ट करने से तेज है? –

+3

मैंने अपना BadImageFormatException तय किया क्योंकि मेरी सीएलआई प्रोजेक्ट x86 मोड में संकलित करने के लिए डिफॉल्ट किया गया था और मेरा सी # ऐप किसी भी CPU मोड में था। इसे बदलें या यह आपके लिए काम कर सकता है। –

उत्तर

55

क्या आपने सी ++/सीएलआई पर एक नज़र डाली है?

मुझे एक बहुत छोटा उदाहरण दें। विज़ुअल सी ++ -> सीएलआर -> क्लास लाइब्रेरी प्रोजेक्ट से स्रोत फ़ाइल यहां दी गई है। यह मूल रूप से विंडोज उपयोगकर्ता नाम प्राप्त करता है और इसे वापस कर देता है।

कृपया ध्यान दें कि, इसे संकलित करने के लिए, आपको परियोजना सेटिंग्स में जाना होगा और "अतिरिक्त निर्भरता" को "माता-पिता से विरासत" के रूप में चिह्नित करना होगा क्योंकि हम उन Windows libs (kernel32.lib, user32.lib, ..)

// CSCPP.h 

#pragma once 

#include "windows.h" 

using namespace System; 

namespace CSCPP { 

    public ref class Class1 
    { 
     // TODO: Add your methods for this class here. 
    public: 
     String^ GetText(){ 
      WCHAR acUserName[100]; 
      DWORD nUserName = sizeof(acUserName); 
      if (GetUserName(acUserName, &nUserName)) { 
       String^ name = gcnew String(acUserName); 
       return String::Format("Hello {0} !", name); 
      }else{ 
       return gcnew String("Error!"); 
      } 
     } 
    }; 
} 

अब एक नया सी # प्रोजेक्ट बनाया और हमारे पहले सी ++/सीएलआई क्लास लाइब्रेरी प्रोजेक्ट में संदर्भ जोड़ें। और फिर इंस्टेंस विधि को कॉल करें।

हैलो m3rlinez:

namespace CSTester 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      CSCPP.Class1 instance = new CSCPP.Class1(); 
      Console.WriteLine(instance.GetText()); 
     } 
    } 
} 

यह मेरा मशीन पर निम्न परिणाम दे दी है!

सी ++/सीएलआई मूल रूप से सी ++ मानक पर एक प्रबंधित विस्तार है। यह आपको सी ++/सीएलआई प्रोजेक्ट में सीएलआर कक्षाओं और डेटा प्रकारों का उपयोग करने की अनुमति देता है और इसे प्रबंधित भाषा में भी बेनकाब करता है। आप इसका उपयोग कर अपने पुराने सी ++ लाइब्रेरी के लिए एक प्रबंधित रैपर बना सकते हैं। सीएलआर स्ट्रिंग में संदर्भ प्रकार को परिभाषित करने के लिए 0 अजीब वाक्यविन्यास जैसे String^ हैं। मुझे यहां उपयोगी होने के लिए "Quick C++/CLI - Learn C++/CLI in less than 10 minutes" मिल गया है।

+3

"अतिरिक्त निर्भरता" सेटिंग पर जाने के लिए प्रोजेक्ट -> गुण -> कॉन्फ़िगरेशन गुण -> लिंकर – Kashif

4

मैं described here के रूप में एक मानक (गैर COM/प्रबंधित) डायनामिक लिंक लाइब्रेरी बनाउंगा और फिर निर्यात किए गए कार्यों तक पहुंचने के लिए C# कोड में DllImport attribute (प्लेटफ़ॉर्म आवेक) का उपयोग करूंगा।

उस लेख से महत्वपूर्ण बिंदु:

नोट __declspec (dllexport) इस कोड में विधि घोषणाओं में संशोधक। इन संशोधक सक्षम विधि है कि यह अन्य अनुप्रयोगों द्वारा इस्तेमाल किया जा सकता DLL तो द्वारा निर्यात किया जाना है। अधिक जानकारी के लिए, देखें dllexport, dllimport।

यह एक वास्तविक COM इंटरॉप आवरण के लिए एक हल्के वजन विकल्प है और इस तरह के पंजीकरण आदि के रूप में मुद्दों से बचा जाता (DLL बस आवेदन निर्देशिका में रखा जा सकता है)।

एक अन्य विकल्प It Just Works (IJW) है। यदि आपने सी ++ कोड प्रबंधित किया है और इसे अन्य .NET भाषाओं से एक्सेस करने की आवश्यकता है तो यह शायद एक बेहतर विकल्प है। लेकिन यह केवल एक विकल्प है यदि आप अपने अप्रबंधित सी ++ को प्रबंधित सी ++ में कनवर्ट करने में सक्षम/खुश हैं।

+2

पी/invoke शब्द का वर्णन करने के लिए प्रयोग किया जाता है। –

+0

मैंने कई लेखों पर पढ़ा है कि यह धीमा है, इसलिए मैं सावधानी के साथ उपयोग करने का सुझाव देता हूं। मैं सी ++ \ सीएलआई और मिश्रित असेंबली का उपयोग करने की सिफारिश करता हूं। – MasterMastic

3

मैं पी/आह्वान से दूर रहने के रूप में यह IJW (यह काम करती है) की तुलना में बहुत धीमी है जाएगा। उत्तरार्द्ध आपको निर्बाध रूप से प्रबंधित और अप्रबंधित सी ++ इंटरवेव करने की अनुमति देता है। आपको केवल एक प्रबंधित सी ++ असेंबली बनाना है, एक प्रबंधित कक्षा लिखें जो सी # से दिखाई दे और उसमें से अप्रबंधित कोड को कॉल करें।

उम ... ठीक है। मैं इस धारणा के तहत था कि पी/आमंत्रण कॉल धीमे थे जो वे विरासत में नहीं हैं। हालांकि, मार्शलिंग पर स्पष्ट नियंत्रण रखते हुए, आप कई मामलों में बेहतर प्रदर्शन करने के लिए अपना सी ++/सीएलआई संस्करण बना सकते हैं।

  • DllImport अप्रबंधित एपीआई कार्यक्रम के लिए घोषणाओं का श्रेय लिखने के लिए कोई जरूरत नहीं है IJW की

    http://msdn.microsoft.com/en-us/library/ms235282.aspx

    लाभ:

    यहाँ दोनों तंत्र के बारे में Microsoft का लेख है का उपयोग करता है। बस में हेडर फ़ाइल और आयात लाइब्रेरी के साथ लिंक शामिल है।

  • IJW तंत्र थोड़ा तेज है (उदाहरण के लिए, IJW स्टब्स नहीं क्योंकि जो डेवलपर के किया जाता है स्पष्ट रूप से पिन करने के लिए या प्रतिलिपि डेटा आइटम की जरूरत के लिए जाँच करने जरूरत है)।
  • यह स्पष्ट रूप से प्रदर्शन समस्याओं को दर्शाता है। इस मामले में, तथ्य यह है कि आप एक यूनिकोड स्ट्रिंग से एएनएसआई स्ट्रिंग में अनुवाद कर रहे हैं और आप में एक सहायक मेमोरी आवंटन और डेलोकेशन है। इस मामले में, IJW का उपयोग कर कोड लिखने वाला डेवलपर यह महसूस करेगा कि PtrToStringChars का उपयोग करके _putws और कॉलिंग बेहतर प्रदर्शन के लिए बेहतर होगा।
  • आप कई अप्रबंधित एक ही डेटा का उपयोग कर एपीआई कॉल करते हैं, यह प्रमुखता एक बार और मार्शल प्रतिलिपि गुजर फिर से प्रमुखता हर बार की तुलना में अधिक प्रभावी है।

रूप में अच्छी तरह सौंदर्य फायदे हैं:

  • सी # कोड किसी भी interop'y weirdness के बिना सी # कोड की तरह दिखता है।
  • आप DLLImport विशेषता को परिभाषित करने की जरूरत नहीं है, तो आप डेटा संरचनाओं में से किसी को परिभाषित करने की जरूरत नहीं है (यह भी पी के साथ/विशिष्ट विशेषताओं के आह्वान) ऐसा दिखाई दे सकता है जो:

    [StructLayout (LayoutKind। अनुक्रमिक, CharSet = CharSet.Ansi)] सार्वजनिक संरचना देवमोड { [मार्शलएएस (UnmanagedType.ByValTStr, SizeConst = 32)] सार्वजनिक स्ट्रिंग dmDeviceName; }

  • आपको सभी पैरामीटर आदिम प्रकारों को उनके .NET समकक्षों में परिवर्तित करने की आवश्यकता नहीं है (this page पर तालिका है जो सूचीबद्ध करता है कि प्रबंधित प्रकार कैसे अप्रबंधित प्रकारों के लिए मानचित्र हैं)।
  • आपको सी ++/सीएलआई के साथ काम करना है जो वास्तव में सीखना मजेदार है और वास्तव में पॉलिश किया गया है। यह वीएस 2003 के बाद से एक लंबा सफर तय किया गया है और अब पूरी तरह से प्रदर्शित .NET भाषा है। इसके लिए माइक्रोसॉफ्ट प्रलेखन बहुत अच्छा है, जैसा कि सभी आईजेडब्ल्यू सूचना है।
  • सी ++/सीएलआई में सी ++ इंटरऑप करना सी # के विपरीत बहुत स्वाभाविक लगता है। यह पूरी तरह से व्यक्तिपरक है, लेकिन मैं सी ++ में स्ट्रिंग मार्शलिंग करना पसंद करूंगा जो Marshal.PtrToString(ptr) करता है।
  • यदि कोई एपीआई उजागर कर रहा है तो आप शायद किसी अन्य परत में सभी पी/आमंत्रण सामग्री को लपेटना चाहेंगे, इसलिए आपको पी/डूबने की ज़रूरत नहीं है। इस तरह आप के चारों ओर सभी marshalling और सी # परत का ओवरहेड है। सी ++/सीएलआई के साथ marshalling और interop abstraction एक ही स्थान पर हैं, और आप चुन सकते हैं कि आपको कितना मार्शलिंग चाहिए।

IMHO यदि आप Windows SDK में एक अजीब समारोह बुला रहे हैं, पी/आह्वान के साथ चलते हैं। यदि आप प्रबंधित दुनिया में मामूली जटिल सी ++ एपीआई का पर्दाफाश कर रहे हैं, तो निश्चित रूप से सी ++/सीएलआई।

+0

एक प्रबंधित रैपर बनाने के बारे में ओपी वार्ता को छोड़कर जिसे मैंने कहा था कि उनके पास पहले से ही अप्रबंधित कोड है। मुझे लगता है कि प्रबंधित सी ++ में फिर से लिखना एक विकल्प हो सकता है। – Ash

+0

क्या आपका मतलब है कि पी/इनवोक कॉल तुलनात्मक रूप से धीमा है, या यह उस प्रदर्शन की तुलना में अधिक प्रदर्शन बाधा है? –

+0

सी ++ पर मोनो पेज के मुताबिक, आईजेडब्ल्यू थंक्स पी/आवेक कॉल हैं। http://www.mono-project.com/CPlusPlus –

8

वहाँ कम से कम तीन तरीके अप्रबंधित कोड एक ही प्रक्रिया में कामयाब से कॉल करने के लिए कर रहे हैं:

  1. C++/CLI
  2. मंच आह्वान
  3. एक COM वस्तु में अपने सी ++ लपेटें

काम पर हम इसके लिए सी ++/सीएलआई का उपयोग करते हैं, ऐसा लगता है कि यह काम करता है।

+3

पर जाएं और अब [CXXI] (http://stackoverflow.com/a/9247254/332026) (स्पष्ट सेक्सी) । – Justin

+2

और CXXI ​​[CppSharp] (https://github.com/mono/CppSharp) –

+0

में morphed प्रतीत होता है और आप काम पर किस तरह का सॉफ्टवेयर लिखते हैं? क्या आप उच्च प्रदर्शन कोड लिखते हैं जहां गति आवश्यक है? –

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