2009-09-24 15 views
5

मेरे पास एक सी # डीएल प्रोजेक्ट है (my_cs_dll.dll) जो स्थैतिक सदस्य फ़ंक्शन वाले स्थिर वर्ग को परिभाषित करता है।आप सी ++ से प्रबंधित (सी #) फ़ंक्शन कैसे कॉल करते हैं?

namespace Foo 
{ 
    public static class Bar 
    { 
     public static double GetNumber() { return 1.0; } 
    } 
} 

मेरे पास एक सी ++ डीएलएल परियोजना भी है जो/clr का उपयोग कर रही है।

#using <my_cs_dll.dll> 

double get_number_from_cs() { return Foo::Bar::GetNumber(); } 

मैं ग में 'my_cs_dll.dll' के लिए एक संदर्भ जोड़ दिया है ++ परियोजना आम गुण का संदर्भ खंड (कॉपी स्थानीय/कॉपी निर्भरता दोनों सच कर रहे हैं)।

और मैंने सी ++ प्रोजेक्ट कॉन्फ़िगरेशन गुण सी/सी ++ सामान्य 'संदर्भों का उपयोग करके # हल करें #) में 'my_cs_dll.dll' का मार्ग भी जोड़ा है।

सबकुछ बिना किसी त्रुटि के बनाता है, हालांकि रनटाइम पर मैं सिस्टम से 'System.IO.FileNotFound' अपवाद प्राप्त करता रहता हूं, यह दावा करता है कि यह my_cs_dll.dll असेंबली नहीं ढूंढ सकता है।

दोनों डीएल निश्चित रूप से उसी निर्देशिका में मौजूद हैं जहां से मैं चल रहा हूं।

मैं सेटिंग्स ऊपर उल्लेख में बदलाव के सभी प्रकार की कोशिश की है और सब कुछ मैं manged/अप्रबंधित इंटरॉप पर मिल सकता है पढ़ा है, लेकिन मैं क्या गलत है चारों ओर मेरे मस्तिष्क पाने के लिए प्रतीत नहीं कर सकते हैं ...

मैं मैं वीएस -2008 & का उपयोग कर रहा हूं .NET 3.5

उत्तर

4

ऐसा लगता है कि आपके सी # असेंबली को रनटाइम पर हल नहीं किया जा रहा है। क्या आपका सी # डीएल आपकी निष्पादन योग्य (या एक उपनिर्देशिका) के समान निर्देशिका में है? यह कुछ समय हो गया है क्योंकि मैंने ऐसा किया है, लेकिन मेरी यादें यह है कि जब तक आपकी असेंबली जीएसी में स्थापित नहीं होती है, तब तक यह निर्देशिका (या एक उपनिर्देशिका) में होनी चाहिए जहां आपका निष्पादन योग्य स्थित है, जो कि उपयोग करने वाले डीएलएल के स्थान के विपरीत है यह। इसे .NET सुरक्षा सुविधाओं के साथ करना है।

यदि आपको अभी भी समस्याएं हैं, तो आप स्वयं असेंबली को हल करने का प्रयास कर सकते हैं। अपने clr-सक्षम सी ++ परियोजना में, निम्न जोड़ने का प्रयास करें:

using namespace System; 
using namespace System.Reflection; 
void Resolve() 
{ 
    AppDomain::CurrentDomain->AssemblyResolve += 
     gcnew ResolveEventHandler(OnAssemblyResolve); 
} 
Assembly ^OnAssemblyResolve(Object ^obj, ResolveEventArgs ^args) 
{ 
#ifdef _DEBUG 
    String ^path = gcnew String(_T("<path to your debug directory>")); 
#else 
    String ^path = gcnew String(_T("<path to your release directory>")); 
#endif 
    array<String^>^ assemblies = 
     System::IO::Directory::GetFiles(path, _T("*.dll")); 
    for (long ii = 0; ii < assemblies->Length; ii++) { 
     AssemblyName ^name = AssemblyName::GetAssemblyName(assemblies[ii]); 
     if (AssemblyName::ReferenceMatchesDefinition(gcnew AssemblyName(args->Name), name)) { 
      return Assembly::Load(name); 
     } 
    } 
    return nullptr; 
} 

आप इसे अपनी परियोजना में संकलित करने के लिए प्राप्त करने के लिए कोड में थोड़ा बदलाव करने पड़ सकता है। मेरे मामले में, मैंने अपने क्लर्क-सक्षम प्रोजेक्ट में दो वर्गों को कक्षा के स्थैतिक तरीकों को बनाया है। बस सुनिश्चित करें कि आप get_number_from_cs() पर कॉल करने का प्रयास करने से पहले, अपने कोड में Resolve() फ़ंक्शन को कॉल करें।

COM का उपयोग करते समय एक विकल्प है, यह आवश्यक नहीं है। आप अपने वर्तमान दृष्टिकोण के साथ सही रास्ते पर हैं। अगर आप कुछ हाथ पकड़ना चाहते हैं, तो इस CodeProject example पर एक नज़र डालें। मेरे प्रबंधित असेंबली का उपयोग करने के लिए मेरा अप्रबंधित एप्लिकेशन प्राप्त करने के लिए यह एक है।

+0

हाय मैट, "यह निर्देशिका (या उप-निर्देशिका) जहाँ आपके निष्पादन स्थित है में, के रूप में है कि यह उपयोग कर रहा है dll के स्थान के विपरीत होना चाहिए" dll के exe के नीचे कई उप-निर्देशिका नेस्टेड रहते हैं । प्रबंधित डीएल को उसी निर्देशिका में ले जाने के रूप में निष्पादन योग्य समस्या को ठीक कर दिया गया। धन्यवाद !! – mark

+0

ठीक है, बढ़िया। मैं इस धारणा के तहत था कि जब तक डीएल निष्पादन योग्य की उपनिर्देशिका में था, भले ही कितना गहराई हो, असेंबली का समाधान हो जाएगा। लेकिन जैसा कि मैंने कहा, यह थोड़ी देर हो गया है क्योंकि मैंने इसे देखा था। –

+0

मैंने एम्बेडेड संसाधन से सी # डीएलएल लोड करते समय समान कोड का उपयोग किया। इस कोड को उस फ़ाइल में रखना था जिसने सी # डीएलएल का संदर्भ नहीं दिया था। ऐसा लगता है कि देरी-भार।नेट असेंबली एक संकलन इकाई (ए। सीपीपी फ़ाइल) में प्रवेश पर होती है जिसमें असेंबली का संदर्भ होता है, न कि जब संदर्भित असेंबली में कॉल वास्तव में किया जाता है, तो कभी भी। – mheyman

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