2012-01-04 30 views
6

का कारण बनता है मैं अपने सी # कार्यक्रम में एक DLL आयात कि इस तरह दिखता है घोषणा की है:एकाधिक समारोह सी # सेल्सियस तक से कॉल ++ अप्रबंधित कोड AccessViolationException

[DllImport("C:\\c_keycode.dll", EntryPoint = "generateKeyCode", 
      CallingConvention = CallingConvention.Cdecl)] 
static extern IntPtr generateKeyCode(char[] serial, char[] option, char c_type); 

यह समारोह generateKeyCode() का संदर्भ मेरी DLL के अंदर।

यहाँ कोड है कि एक त्रुटि (प्रयुक्त breakpoints) खड़ी कर रहा है है:

const char* generateKeyCode(char serial[], 
       char option[], 
       char c_type) 
{ 
returnBufferString = ""; 
SHA1_CTX context; 
int optionLength = 0; 
#ifdef WIN32 
unsigned char buffer[16384] = {0}; 
#else 
unsigned char buffer[256] = {0}; 

#endif 
//char output[80]; 
char keycode[OPTION_KEY_LENGTH+1]  = ""; 
int digest_array_size = 10; //default value for digest array size 
unsigned char digest[20] = {0}; 
char optx[24] = {0}; 
char c_type_upper; 
// Combine serial # and Option or Version number 

char str1[30] = {0}; 
int i; 
int size = 0; 
int pos = 0; 


... 
... 
} 

मूल रूप से, मैं इस DLL आयातित तो मैं समारोह पैरामीटर पास कर सकता है और वह अपने एल्गोरिथ्म करते हैं और बस मुझे एक परिणाम लौट सकते हैं । मैं इस marshaler समारोह ...

public static string genKeyCode_marshal(string serial, string option, char type) 
{ 
    return Marshal.PtrToStringAnsi(generateKeyCode(serial.ToCharArray(), 
      option.ToCharArray(), type)); 
} 

इस्तेमाल किया ... तो मैं कॉल ठीक से कर सकता है। मेरी सी ++ हेडर फ़ाइल के अंदर, मैंने एक स्ट्रिंग को परिभाषित किया है, जैसा कि इंगित किया गया है question के उत्तर में यह उपयोगी है (यह returnBufferString सी/सी ++ फ़ंक्शन के शीर्ष पर मौजूद चर) है।

मैं इस फ़ंक्शन को कई बार कॉल करता हूं क्योंकि मैं NumericUpDown नियंत्रण का उपयोग 1.0 से 9.9 तक 0.1 की वृद्धि में (प्रत्येक ऊपर या नीचे किसी अन्य फ़ंक्शन कॉल के साथ), और फिर फिर से नीचे आ जाता है। हालांकि, हर बार जब मैं ऐसा करने का प्रयास करता हूं, तो प्रोग्राम फ़ंक्शन कॉल की प्रतीत होने वाली सेट संख्या के बाद हिट करता है (अगर मैं सीधे ऊपर और नीचे जाता हूं, या इससे पहले कि अगर मैं थोड़ा ऊपर और नीचे जाता हूं तो पीछे की ओर 1.9 पर रुक जाता है) ।

कृपया ध्यान दें कि यह काम करता है और मुझे वह मूल्य देता है जो मुझे चाहिए, वहां कोई विसंगति नहीं है।

मैंने बफर आकार को कुछ छोटे नंबर (5012) में बदल दिया और जब मैंने प्रोग्राम चलाने की कोशिश की, तो पहले फ़ंक्शन कॉल पर यह AccessViolationException को फेंक दिया। हालांकि, बफर आकार को दोगुना करने के लिए दो बार (32768) मूल के मुकाबले मूल पर तुलना नहीं हुई थी - सीधे 9.9 से 9.9 तक और नीचे फिर से, यह 1.9 पर बंद हो जाती है और अपवाद फेंकता है।

संपादित करें: डिफ़ॉल्ट एएनएसआई है, इसलिए यह एएनएसआई है। वहां कोई समस्या नहीं है। क्या यह एक स्मृति आवंटन मुद्दा है ??

+0

आगे परीक्षण पर, ऐसा लगता है कि फ़ंक्शन में मेमोरी समस्याएं हैं, भले ही इसे एक बार में कहां या कहां कहा जाता है, मेरे डीबग प्रिंट-आउट से पता चलता है कि स्ट्रीम में कचरा मूल्यों का एक गुच्छा है, और इसलिए गलत कुंजी उत्पन्न करता है। मुझे लगता है कि यह शायद संबंधित है। –

+0

सी # में एक चार 2 बाइट चौड़ा है। सी में, char केवल 1 बाइट है (मुझे लगता है कि आपको कंपाइलर विकल्पों के आधार पर 2 बाइट्स होने के लिए wchar_t होने की आवश्यकता होगी)। मैं वहां से शुरू करूंगा। –

उत्तर

0

मैं इस असंतोषजनक हो सकता है, लेकिन एक बार मैं उत्पादन पुनर्निर्देशन मैं अपने C/C++ DLL के भीतर से डिबग करने के लिए उपयोग कर रहा था हटा दिया, समस्या बंद कर दिया । सबकुछ अब काम करता है, इसलिए मुझे लगता है कि यह अनिवार्य रूप से मेरे अपने प्रश्न का उत्तर देने के बराबर है। उत्तरों के लिए सभी को धन्यवाद।

2

मैं निम्नलिखित की कोशिश कर रहा सुझाव है:

[DllImport("C:\\c_keycode.dll", EntryPoint = "generateKeyCode", 
     CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] 
static extern IntPtr generateKeyCode(string serial, string option, char c_type); 

नोट DllImport विशेषता के नए CharSet क्षेत्र।

अगला विचार MarshalAs विशेषता पर स्पष्ट रूप उपयोग करने के लिए है:

[DllImport("C:\\c_keycode.dll", EntryPoint = "generateKeyCode", 
     CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)] 
static extern IntPtr generateKeyCode([MarshalAs(UnmanagedType.LPTStr)] string serial, [MarshalAs(UnmanagedType.LPTStr)] string option, char c_type); 
+0

हाय क्रिज। यह मुझे मिला। 1 आगे (मुझे वापस रास्ते पर 2.0 के बजाय 1.9 तक पहुंचा)। मैंने इसके बारे में सोचा था लेकिन ऐसा नहीं सोचा था कि इससे मदद मिलेगी। हालांकि उत्तर के लिए धन्यवाद। –

+0

क्या आपने दोनों की कोशिश की है? मैंने एक संपादन जोड़ा है। – Krizz

+0

हो सकता है, लेकिन बिंदु 'char [] 'का उपयोग करने के बजाय सीआरआर पर मार्शल' स्ट्रिंग 'पर भरोसा करना है। क्या आपने इसे भी बदल दिया है? – Krizz