2013-01-16 5 views
6

मान लें के बाद एक तरह एक शुद्ध सी इंटरफेस के साथ एक देशी समारोह, एक देशी DLL से निर्यात किया है कि वहाँ:पी/Invoke [इन, आउट] विशेषताएँ मार्शलिंग सरणी के लिए वैकल्पिक हैं?

// NativeDll.cpp 

extern "C" void __stdcall FillArray(
    int fillValue, 
    int count, 
    int* data) 
{ 
    // Assume parameters are OK... 

    // Fill the array 
    for (int i = 0; i < count; i++) 
    { 
     data[i] = fillValue; 
    } 
} 

निम्नलिखित पी/आह्वान ठीक काम करता है (VS2010 SP1 के साथ परीक्षण किया गया):

[DllImport("NativeDll.dll", CallingConvention=CallingConvention.StdCall)] 
public static extern void FillArray(
    int fillValue, 
    int count, 
    [In, Out] int[] data 
); 

के साथ ही इस पी/आह्वान, ऊपर के रूप में ही है, लेकिन बिना [In, Out] गुण:

[DllImport("NativeDll.dll", CallingConvention=CallingConvention.StdCall)] 
public static extern void FillArray(
    int fillValue, 
    int count, 
    int[] data 
); 

तो, [In, Out] विशेषताएँ वैकल्पिक मार्शलिंग सरणी के लिए हैं? उनका उद्देश्य क्या है, यदि कोई है? क्या यह हमारे पी/आमंत्रण घोषणाओं में उन्हें छोड़ना ठीक है?

उत्तर

16

नहीं, वे बिल्कुल वैकल्पिक नहीं हैं। यह सिर्फ दुर्घटना से काम करने के लिए होता है। हालांकि यह एक बहुत ही आम दुर्घटना है। यह काम करता है क्योंकि सरणी वास्तव में मार्शल नहीं होती है। पिनवोक मार्शलर देखता है कि सी # सरणी देशी सरणी के साथ पहले ही संगत है इसलिए इसकी प्रतिलिपि बनाने के लिए चरण को छोड़ देता है। यह केवल सरणी पिन करता है और पॉइंटर को देशी कोड में पास करता है।

यह निश्चित रूप से बहुत ही कुशल है और आप अनिवार्य रूप से परिणाम वापस प्राप्त करेंगे क्योंकि मूल कोड सरणी तत्वों को सीधे लिख रहा है। तो न तो [इन] और न ही [आउट] विशेषताएँ मायने रखती हैं।

यदि सरणी तत्व प्रकार इतना आसान नहीं है तो यह बहुत ही मजेदार हो जाता है। किसी तत्व प्रकार की पहचान करना इतना आसान नहीं है जो एक संरचना या वर्ग प्रकार है जो धुंधला नहीं है या जिसका लेआउट मार्शलिंग के बाद मेल नहीं खाता है, इसलिए पिनवोक मार्शलर में है जो सरणी की एक प्रति बनाने के लिए है। विशेष रूप से लेआउट असंगतता बहुत पहचानने में कठोर हो सकती है क्योंकि प्रबंधित लेआउट अनदेखा है। और इस्तेमाल किए गए जिटर के आधार पर बदल सकते हैं। यह x86 में काम कर सकता है लेकिन x64 नहीं, उदाहरण के लिए, जब भी कोई भीCPU चुना जाता है तो बहुत बुरा होता है। इसे संशोधित प्रतिलिपि को वापस सी # सरणी पर कॉपी करने के लिए की आवश्यकता है [आउट]।

सुनिश्चित नहीं है कि सलाह क्या है, इसके अलावा किसी भी को कभी भी उनकी घोषणाओं में स्पष्ट होने के लिए निकाल दिया गया है। शायद आपको हमेशा स्पष्ट होना चाहिए जब सरणी तत्व प्रकार सरल नहीं है, तो आपको कभी दुर्घटना नहीं होगी।

+1

उह ... मैंने x86/x64/'किसी भी CPU' के बीच मार्शलिंग effups के अपने जीवन समस्या निवारण के इतने घंटे बिताए हैं ... – JerKimball

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