2012-11-08 14 views
6

पिनिंग ऐरे ऑब्जेक्ट्स पर कुछ प्रोसेसिंग करने के लिए देशी फ़ंक्शन को अनुमति देने के लिए मैं .NET ऑब्जेक्ट्स (ऑब्जेक्ट्स सहित) की एक सरणी पिन करना चाहता हूं। जहां तक ​​मुझे समझा गया, GCHandle.Alloc() मुझे ऐसा करने की अनुमति नहीं देता है, क्योंकि इस तरह के सरणी में संदर्भ होते हैं (और वस्तुओं में संदर्भ भी हो सकते हैं) जो कि विचित्र नहीं हैं।.NET ऑब्जेक्ट्स

क्या यह हासिल करने के लिए कोई अन्य विकल्प है? मैं बहुत हैक-वाई सुझावों के साथ ठीक हूं या जिनके लिए मोनो की आवश्यकता होती है।

+0

क्या आप भले ही आप उन्हें मिल सकता है पिन किए गए इन वस्तुओं के लिए ऐसा करने में सक्षम होने की उम्मीद करते हैं? संदर्भ जरूरी नहीं हैं पॉइंटर्स; आप उन्हें मूल पक्ष से नहीं पहुंच पाएंगे। – MikeP

उत्तर

9

.NET में Arrays को संगत स्मृति में दर्शाया गया है। तो इसका मतलब है कि स्मृति में, तत्व 0 के बाद, तत्व 1 सीधे पिछले तत्व के बाद आएगा, और इसी तरह।

यदि आप GCHandle.Alloc के साथ सरणी पिन, तो इसका मतलब है कि तत्वों की पूरे सूची के रूप में अच्छी तरह से स्मृति में पिन किया गया है, और आप संसाधित कर सकते हैं कि अप्रबंधित कोड में।

हालांकि, जैसा कि आपने उल्लेख किया है, यह केवल तभी समझ में आता है जब यह प्रकार एक विचित्र प्रकार है (तकनीकी रूप से, यह सच नहीं है, यह है कि अगर प्रकार अप्रबंधित कोड पर मार्शल किया जा सकता है, हालांकि बहुत अधिक ओवरलैप है यहाँ ब्लिटेबल प्राथमिक प्रकारों और सामानों के बीच जो पी/Invoke/COM इंटरऑप परत स्वचालित रूप से संभालते हैं)।

तो यदि आपके पास मूल्य प्रकारों की एक सरणी है, तो आप GCHandle.Alloc पर कॉल कर सकते हैं और यह आपके लिए सरणी पिन करेगा। हालांकि, पी/Invoke परत पहले से ही यह आपके लिए करता है, इसलिए आपको इससे चिंतित नहीं होना चाहिए।

यदि आपकी सरणी संदर्भों से भरी है, तो इसे असम्बद्ध कोड पर मार्शल करना किसी भी तरह से समझ में नहीं आता है; यहां तक ​​कि यदि आप प्रत्येक संदर्भ को पिन करते हैं, तो अप्रबंधित कोड को यह नहीं पता होगा कि स्मृति में उस संदर्भ के साथ क्या करना है, क्योंकि प्रकार सिस्टम .NET प्रकार का समर्थन नहीं करता है जो संदर्भ स्मृति में इंगित कर रहा है।

यदि .NET में कक्षा वास्तव में एक देशी संरचना का एक रैपर/.NET प्रतिनिधित्व है, तो आप .NET में उस संरचना की सरणी बनाने से बेहतर हैं, इसमें सभी डेटा कॉपी कर रहे हैं, और फिर इसे भेज रहे हैं अपने मूल कोड के लिए।

या, आप मूल कोड में .NET सदस्यों की पहुंच को सुविधाजनक बनाने के लिए सी ++/क्ली में अपनी कक्षा लिख ​​सकते हैं।

+0

@casperOne - मैं संदर्भों से भरा एक सरणी का जिक्र कर रहा था। मेरे परिप्रेक्ष्य से, सरणी को पिन करना और सरणी द्वारा संदर्भित हर ऑब्जेक्ट को समझ में आता है। सी कोड को सिर्फ यह पता होना चाहिए कि यह सी # सरणी और सी # ऑब्जेक्ट्स से निपट रहा है और अपने क्षेत्र को पॉइंटर अंकगणितीय के माध्यम से एक्सेस करता है जो सीएलआर के डिफ़ॉल्ट मेमोरी लेआउट की नकल करता है। – user1622959

+0

यदि आपको संदर्भों से भरा सरणी मिलती है, तो सरणी को पिन करें और सरणी में सभी संदर्भों को पिन करें, आपको अभी भी मेरे पांचवें पैराग्राफ में जो कुछ बताया गया है उससे निपटना होगा: आपको नहीं पता कि मूल प्रणाली में टाइप सिस्टम क्या है, तो उन पॉइंटर्स का मतलब आपके लिए कुछ भी नहीं है। यदि आप * पहले से ही मिश्रित कोड (.NET और C++ कोड) के लिए C++/CLI का उपयोग कर रहे हैं तो आपको केवल उस वर्ग/विधि का खुलासा करना चाहिए जो .NET प्रकार को शुरू करने के लिए लेता है, क्योंकि आप इसे करने से कुछ हासिल नहीं कर रहे हैं। – casperOne

+0

अब तक मैं संदर्भों के साथ एक सरणी को पिन करने में सफल नहीं हुआ (संदर्भ प्रकार के सदस्यों के साथ एक वस्तु के लिए), क्या यह संभव है? आपके पांचवें पैराग्राफ में: एक बार जब मुझे पिनिंग समस्या का हल हो जाए, तो यह अगली चुनौती होगी - .NET मेमोरी लेआउट का विश्लेषण करना और सी फ़ंक्शन लिखना जो कि सी – user1622959

0

आप Marshal.AllocHGlobal और Marshal.WriteIntPtr पर एक नज़र डाल सकते हैं। यह आधिकारिक तरीका है कि ढांचा अप्रबंधित स्मृति के साथ काम करने के लिए प्रदान करता है। यकीन नहीं है कि यह मददगार होगा हालांकि।

संपादित

भी देखें https://stackoverflow.com/a/878147/301525

+1

यह सवाल का उत्तर कैसे देता है? – casperOne

+0

@casperOne - मेरी कल्पना मुझे बताती है कि क्या वह प्रश्न में जो कुछ भी पूछता है उसे पूरा करना चाहता है, एकमात्र तरीका यह है कि अगर वह अपने सभी सरणी को अप्रबंधित ब्लॉक में मार्शल करता है। – m0s

+0

पी/Invoke या COM इंटरऑप परतें आपके लिए यह स्वचालित रूप से करते हैं। – casperOne

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