2011-12-06 24 views
7

से प्रबंधित .NET कोड को कॉल करने का सबसे अच्छा तरीका मैं अप्रबंधित सी ++ कोड से प्रबंधित .NET कोड में कॉल करने का सर्वोत्तम प्रदर्शन करने का तरीका ढूंढ रहा हूं। मुझे अपने सी ++ एप्लिकेशन के भीतर होस्टिंग .NET पर जानकारी मिली है और मैं एक pRuntimeHost बनाने और बिना किसी समस्या के इसे शुरू करने में सक्षम हूं।अप्रबंधित कोड

ExecuteInDefaultAppDomain बहुत सीमित लगता है क्योंकि मैं वास्तव में इसे कुछ पैरामीटर भेजना चाहता हूं और इसे जानकारी की संरचना वापस कराना चाहता हूं। सबसे स्पष्ट विकल्प COM विधियों का उपयोग करना है, लेकिन वर्तमान सी # कोड वास्तव में विधियों के साथ इंटरफेस के रूप में सेटअप नहीं है।

किसी भी तरह से मैं पूर्णांक, तार (char *) एस, युगल और अन्य कोर सी ++ प्रकारों को वापस करना चाहता हूं। सी ++ से सी # को परिवर्तित करने के लिए दोनों तरफ बहुत अधिक कोड है और प्रबंधित सी ++ का उपयोग स्वीकार्य समाधान नहीं है, क्योंकि इस सी ++ कोड का उपयोग करने वाले अन्य समूह प्रदर्शन कारणों से प्रबंधित कोड का उपयोग शुरू नहीं करना चाहते हैं।

लक्ष्य मौजूदा सी ++ और सी # कोड को जितना संभव हो सके संशोधित करता है लेकिन सी ++ कोड के गति को प्रभावित करने के बिना सी ++ के भीतर विशिष्ट बिंदुओं पर सी # कोड के भीतर विधियों का उपयोग करता है।

इंटरनेट स्टार्टअप और शट डाउन अनुक्रम नेट की मेजबानी के लिए पर पाया कोड पर आधारित है:

#include "stdafx.h" 
#include <metahost.h> 

#pragma comment(lib, "mscoree.lib") 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    ICLRMetaHost  *pMetaHost  = NULL; 
    ICLRMetaHostPolicy *pMetaHostPolicy = NULL; 
    ICLRDebugging  *pCLRDebugging = NULL; 

    HRESULT hr; 
    hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID*)&pMetaHost); 
    hr = CLRCreateInstance(CLSID_CLRMetaHostPolicy, IID_ICLRMetaHostPolicy, (LPVOID*)&pMetaHostPolicy); 
    hr = CLRCreateInstance(CLSID_CLRDebugging, IID_ICLRDebugging, (LPVOID*)&pCLRDebugging); 

    DWORD dwVersion = 0; 
    DWORD dwImageVersion = 0; 
    ICLRRuntimeInfo *pRuntimeInfo; 
    hr = pMetaHost->GetRuntime(L"v4.0.30319", IID_ICLRRuntimeInfo, (LPVOID *)&pRuntimeInfo); 

    ICLRRuntimeHost * pRuntimeHost = NULL; 
    hr = pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (LPVOID *)&pRuntimeHost); 

    hr = pRuntimeHost->Start(); 

    DWORD dwRetCode = 0; 
    //hr = pRuntimeHost->ExecuteInDefaultAppDomain(argv[1], L"MyNamespace.MyClass", L"Message", L"Hello World!", &dwRetCode); 

    // Stop the CLR runtime and shutdown cleanly. 
    hr = pRuntimeHost->Stop(); 
    hr = pRuntimeHost->Release(); 
    hr = pRuntimeInfo->Release(); 
    hr = pCLRDebugging->Release(); 
    hr = pMetaHostPolicy->Release(); 
    hr = pMetaHost->Release(); 

    return 0; 
} 

उत्तर

5

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

  1. मूल सी ++ इंटरफेस लिखें जो आवश्यक .Net funcionality का प्रतिनिधित्व करता है।

  2. सीएलआर समर्थन के साथ एक डीएलएल सेट करें जो उमने वाले वर्गों का उपयोग करके मूल इंटरफेस लागू करता है। उनके कार्यान्वयन के अंदर आप gcroot<T> फ़ील्ड में सीएलआर प्रकारों और स्टोर इंस्टेंस चरों को बना सकते हैं और एक्सेस कर सकते हैं। marshal_as के लिए प्रबंधित/अप्रबंधित कोड, Google या बिंग के बीच आगे और पीछे मार्शल में क्लियर इंटरऑप funcionality का उपयोग करें।

  3. एक (अप्रबंधित) फैक्ट्री फ़ंक्शन प्रदान करें, जो इस घटक का एक उदाहरण बनाता है। यह + अप्रबंधित सी ++ इंटरफ़ेस एपीआई है जो आपका मूल कोड देखेंगे। डीएलएल का प्रयोग उसी तरह करें जब आप एक अप्रबंधित डीएलएल का उपयोग करेंगे।

+0

अतिरिक्त ऐपडोमेन बनाने का कारण यह है कि सी ++ कोड पहले से ही कुछ सामानों के लिए डिफ़ॉल्ट ऐपडोमेन का उपयोग कर रहा है और मैं नहीं चाहता कि मेरा अतिरिक्त .NET असेंबली वर्तमान कोड में हस्तक्षेप करे और साथ ही साथ उनकी सामग्री में हस्तक्षेप न करें । बीटीडब्ल्यू मैंने सीएलआई परत को पूरी तरह से काम करने में कामयाब रहा लेकिन मैं अभी भी यह समझने की कोशिश कर रहा हूं कि पूरी सीएलआई परत को एक अलग ऐपडोमेन में कैसे प्राप्त किया जाए जो डिफ़ॉल्ट ऐपडोमेन नहीं है। –

+0

अभी तक ऐसा करने की कोशिश नहीं की है, लेकिन सैद्धांतिक रूप से यह कोई समस्या नहीं होनी चाहिए। मैं समझता हूं कि आपका परिदृश्य देशी से एक प्रबंधित घटक में कॉल करना है, है ना? "थ्रेड प्रमोशन" (google या bing) नामक एक सुविधा है जो किसी देशी थ्रेड को किसी प्रबंधित व्यक्ति को प्रचारित करने का कारण बनती है, जब भी यह पहले प्रबंधित कोड निष्पादित करने का प्रयास करती है। चूंकि सीएलआर को कोई एहसास नहीं है कि ऐपडोमेन प्रबंधित कोड को उस तरीके से निष्पादित किया जाना चाहिए, यह इसे डिफ़ॉल्ट में डाल देता है। तो आपको शायद उस संक्रमण को 'msclr :: call_in_appdomain' परिवार का उपयोग करके उस संक्रमण को स्पष्ट रूप से संभालना होगा। –

+0

मैंने इस स्थान पर अपना अंतिम समाधान दस्तावेज किया है: http://stackoverflow.com/questions/10301727/marshalling-c-pointer-interface-back-though-c-sharp-function-call-in-a-non-def –

3

यदि यह स्वीकार्य है, सबसे अच्छा समाधान एक प्रबंधित सी ++ dll कि बैठता है बनाने के लिए किया जा सकता है के बीच । प्रबंधित सी ++ कोड ब्रिज प्रबंधित और अप्रबंधित कोड का सबसे अच्छा/सबसे प्रभावी तरीका है।

आप वास्तव में मिश्रण में COM को जोड़ना नहीं चाहते हैं। इससे चीजों को और धीमा कर दिया जाएगा।

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

+0

प्रदर्शन microseconds में गिना जा रहा है। तो इसके बाद मैंने सी ++ std :: मानचित्र के रूप में अनुरोध/प्रतिक्रिया के कैशिंग को जोड़ा है। यह सी # परत पर वापस जाने के बिना पहले से अनुरोध किए गए किसी भी चीज़ के लिए त्वरित लुकअप की अनुमति देता है। मैंने ऊपर अतिरिक्त जानकारी संलग्न की है। –

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

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