2012-05-03 17 views
10

से सी डीएल को कॉल करना हाय मेरे पास एक ऐसे फ़ंक्शन के साथ एक डीएलएल है जिसे मुझे कॉल करने की आवश्यकता है। हस्ताक्षर है:सी ++, सी # और रूबी

const char* callMethod(const char* key, const char* inParams); 

मैं गहरे लाल रंग का सब कुछ का उपयोग करते हैं ठीक काम करता है:

attach_function :callMethod, [:string, :string], :string 

अगर मैं का उपयोग सी ++ या सी # मैं ढेर अतिप्रवाह प्राप्त करें!?

सी #:

[DllImport("DeviceHub.dll", CallingConvention = CallingConvention.Cdecl)] 
private unsafe static extern IntPtr callMethod(
    [MarshalAs(UnmanagedType.LPArray)] byte[] key, 
    [MarshalAs(UnmanagedType.LPArray)] byte[] inParams 
); 

System.Text.UTF8Encoding encoding = new UTF8Encoding(); 
IntPtr p = callMethod(encoding.GetBytes(key), encoding.GetBytes(args)); // <- stack overflow here 

C++:

extern "C" 
{ 
typedef DllImport const char* ( *pICFUNC) (const char*, const char*); 
} 
HINSTANCE hGetProcIDDLL = LoadLibrary(TEXT("C:\\JOAO\\Temp\\testedll\\Debug\\DeviceHub.dll")); 
FARPROC lpfnGetProcessID = GetProcAddress(HMODULE (hGetProcIDDLL),"callMethod");*  pICFUNC callMethod; 
callMethod = (pICFUNC) lpfnGetProcessID; 
const char * ptr = callMethod("c", "{}"); 

मैं समारोह फोन करने के लिए विविधताओं के बहुत सारे की कोशिश की है: WINAPI, पास्कल, stdcall, fastcall, ... कुछ भी नहीं काम करता है।

डीएलएल मेरे द्वारा नहीं बनाया गया है और मेरे पास इसका कोई नियंत्रण नहीं है।

क्या कोई मुझे किसी भी सुझाव के साथ मदद कर सकता है !?

+0

आप एक विचार करने के लिए मेरे प्रश्न पर एक नज़र डाल सकते हैं। यहाँ एक [कड़ी] [1] [1]: http://stackoverflow.com/questions/7153521/pass-multi-dimensional-array-from-managed-code-to-unmanaged-code –

+2

सी # में दो पैरामीटर के प्रकारों के लिए आप 'स्ट्रिंग' का उपयोग क्यों नहीं करते? – Ove

+0

मेरा विश्वास करो मैंने बहुत कुछ खोजा है ... :)। मैंने स्ट्रिंग्स के साथ भी कोशिश की है लेकिन सी # समस्याओं से बचने के लिए मैंने पुराने अच्छे सी ++ के साथ भी परीक्षण किया है और अभी भी ढेर ओवरफ्लो है! – Joao

उत्तर

-5

स्टैक ओवरफ़्लो अपवाद अनंत रिकर्सन को रोकने के लिए माइक्रोसॉफ्ट भाषाओं में एक त्रुटि है, और असंगत प्रोग्रामों को एक दूसरे के साथ बातचीत करने से रोकने के लिए एक त्रुटि है। यदि आपकी डीएलएल विधि रिकर्सन का उपयोग करती है, तो इसे पुनरावृत्ति के साथ पुनः लिखने का प्रयास करें। अन्यथा, ओवे ने कहा, और तारों के साथ प्रयास करें। यदि यह अभी भी काम नहीं करता है, तो Google एक संगत प्रकार के लिए। असली विधि जानने के बिना मैं यही कह सकता हूं।

+0

"* स्टैक ओवरफ़्लो अपवाद अनंत रिकर्सन को रोकने के लिए माइक्रोसॉफ्ट भाषाओं में एक त्रुटि है, और असंगत प्रोग्रामों को एक दूसरे के साथ बातचीत करने से रोकने के लिए है। *" आपको यह विचार कहां मिला?आप किसी भी प्लेटफ़ॉर्म पर स्टैक को ओवरफ़्लो कर सकते हैं ... – ildjarn

+0

सरल, मैंने इसे अपनी खुद की समस्या के समाधान के लिए Google के दौरान माइक्रोसॉफ्ट वेबसाइट पर पढ़ा है। समाधान इसे पुनरावृत्त करने के लिए बदल रहा था। – m12

+0

मेरा मुद्दा यह है कि यह किसी भी तरह से माइक्रोसॉफ्ट भाषाओं/प्लेटफार्मों के लिए विशिष्ट नहीं है, और न ही असंगत कार्यक्रमों को एक दूसरे के साथ बातचीत करने से रोकने के लिए है (यह कभी-कभी एक दूसरे के साथ बातचीत करने वाले असंगत कार्यक्रमों को _caused किया जाता है)। – ildjarn

1

सुनिश्चित करें कि आपके शीर्षक में घोषणा एक निर्वासन 'सी' ब्लॉक में संलग्न है बनाओ:

extern "C" { 

const char* callMethod(const char* key, const char* inParams); 

} 

देखें http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html#faq-32.3

+0

मैंने अपने प्रश्न में सी ++ कोड बदल दिया है। – Joao

1

यह सिर्फ एक विचार है लेकिन AFAIK इस null- के साथ एक समस्या हो सकती है समाप्त तार, const char* myvar शून्य-समाप्त हो गया है लेकिन बाइट सरणी नहीं है। आपको जिस चीज की आवश्यकता है उसे कॉल को ...(String a, String b) पर बदलना है और उन्हें LPStr के रूप में मार्शल करना है।

+0

वही बात! System.stackoverflow अपवाद – Joao

+0

@ जोआओ मुझे यकीन है कि त्रुटि स्वयं कॉल द्वारा उत्पन्न नहीं होती है (मुझे यकीन है कि उपरोक्त कॉल सही है), आपके द्वारा कॉल की जाने वाली विधि में कोई त्रुटि हो सकती है क्योंकि एक ढेर -फ्लोफ उत्पन्न होता है जब स्टैक पर अधिक डेटा होता है, इसके कई कारण हो सकते हैं। –

+0

हाँ आप सही हैं। लेकिन जो चीज मुझे परेशान करती है वह तथ्य यह है कि रूबी काम करता है ... मुझे रूबी बहुत अच्छी तरह से नहीं पता है और मैं इस संभावना पर विचार कर रहा हूं कि रुबी कॉल और सी ++ या सी # कॉल के बीच कुछ मौलिक मतभेद हैं जो ऐसा हो रहा है। एक और मुद्दा शायद कुछ संकलक विकल्प है। – Joao

0

मैं कोई कारण नहीं क्यों आप

[DllImport("DeviceHub.dll", CallingConvention = CallingConvention.Cdecl)]
private unsafe static extern string callMethod(
string key,
string inParams
);

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

+0

एक ही बात! system.stackoverflow अपवाद – Joao

+0

क्या आप अपना बदला कोड दिखा सकते हैं? इसके अलावा मैं निर्भर मुद्दों के लिए http://www.dependencywalker.com/ का उपयोग करूंगा। – weismat

+0

मैंने आपके कोड खंड के रूप में बिल्कुल किया है और [मार्शलएएस (UnmanagedType.LPStr)] के साथ भी प्रयास किया है। जिस तरह से मैं कॉल कर रहा हूं वह प्रतिक्रिया है = callMethod (कुंजी, तर्क); जहां कुंजी और तर्क प्रकार स्ट्रिंग – Joao