2012-07-09 16 views
8

मुझे एक अप्रबंधित टीसीपी रिसीवर को प्रबंधित कॉलबैक पास करने की आवश्यकता है। चूंकि यह एक धागा है जो आवेदन के जीवनकाल के लिए मौजूद होना आवश्यक है, इसलिए मुझे इसे कचरा इकट्ठा करने से रोकने की जरूरत है। मैंने हर जगह पढ़ा है कि फ़िनिंग पॉइंटर्स को पिन करना आवश्यक नहीं है और GCHandle.Alloc कचरा संग्रह को रोकने का काम करेगा।एक फ़ंक्शन पॉइंटर पिन करें

लेकिन क्या यह एक दिया गया है? मैंने देखा है कि इस कोड को होस्ट करने वाला ऐपपूल एक्सेस उल्लंघन के साथ दुर्घटनाग्रस्त हो जाता है। मुझे इस तथ्य पर संदेह क्यों नहीं होना चाहिए कि यह त्रुटि तब होती है क्योंकि फ़ंक्शन पॉइंटर कचरा इकट्ठा किया गया था?

यह post इस तथ्य का समर्थन करता है।

अद्यतन: ऐसा लगता है कि दुर्घटनाओं में काफी कमी आई है। क्या इस दृष्टिकोण में कोई समस्या है?

typedef void (__cdecl *ProcMessageFunc)(void* param, void* paramBuf, ULONG bufSize); 
FuncDelegate^ fp = gcnew MessageFuncDelegate(this, &Handler); 
pin_ptr<MessageFuncDelegate^> pinnedFunctionPointer = &fp; 
ret = Receiver ((ProcMessageFunc)pinnedFunctionPointer); 
+3

एक स्थिर चर में प्रतिनिधि वस्तु को संग्रहीत करना पर्याप्त है। कई अन्य कारणों से पहुंच उल्लंघन के साथ मूल कोड बम कर सकता है। –

+0

मैंने बिल्कुल ऐसा किया है। कारण है कि मैं कचरा संग्रह पर शक करने की ओर अग्रसर हूं क्योंकि कारण उल्लंघन उल्लंघन गलत तरीके से होता है। और अधिक महत्वपूर्ण बात यह है कि क्रैश डंप में कॉल स्टैक मैं देशी dll को clr.dll के बाद और फिर stack के शीर्ष पर kernel32.dll देख सकता हूं। यह आदेश सुसंगत है। – Krishter

उत्तर

8

मैं बिल्कुल ऐसा तुम क्या करने का सुझाव देते हैं क्या - प्रतिनिधि पर लेकिन कोई पिन करने के साथ GCHandle.Alloc - और कई विभिन्न प्लेटफार्मों पर और .NET संस्करण पर 2.0 बड़े पैमाने पर इस्तेमाल में कोई समस्या नहीं पड़ा है - 4. कुछ जैसे:

DelegateHandle = GCHandle.Alloc(xlDelegate); 
FunctionPointer = Marshal.GetFunctionPointerForDelegate(xlDelegate); 

FunctionPointer साथ तो मूल कोड को पारित कर दिया, और DelegateHandle बाद में सफाई के लिए रखा है।

यह सबसे अच्छा संदर्भ प्रतीत होता है: http://msdn.microsoft.com/en-us/library/367eeye0(v=vs.80).aspx

इस संदर्भ में आप जिस पोस्ट को इंगित करते हैं उसमें कुछ भी नहीं - आपको प्रतिनिधि को कचरा संग्रह से बचाने की आवश्यकता है, यह केवल पिनिंग की आवश्यकता नहीं है

+0

क्या कार्यों के लिए पता-पिनिंग आवश्यक नहीं है क्योंकि ढेर वस्तुओं के विपरीत वे एक स्थिर स्थान में मौजूद हैं? एक समारोह में क्या पता है यदि यह अभी तक JIT'd नहीं है? – Dai

+2

मुझे लगता है कि GetFunctionPointerForDelegate को कॉल करने के लिए एक छोटा मार्शलिंग स्टब बनाता है जिसमें एक निश्चित प्रविष्टि बिंदु होता है, लेकिन यदि प्रतिनिधि स्थानांतरित हो जाता है तो स्टब अभी भी इसे कॉल करने के बारे में बताएगा। तो निर्यातित फ़ंक्शन पॉइंटर प्रतिनिधि ऑब्जेक्ट के पते का प्रत्यक्ष निर्यात नहीं है (पिन किए गए सरणी या स्ट्रक्चर सदस्य के विपरीत) होगा। याद रखें कि निर्यात किए गए 'देशी' फ़ंक्शन को मूल -> प्रबंधित संक्रमण भी लागू करना चाहिए। – Govert

+0

यह वही है जो मैंने किया है। दुर्भाग्यवश एक्सेस उल्लंघन अभी भी होता है। मुझे इसे इस तरह करने दो. मैं पूरी तरह से कैसे सुनिश्चित कर सकता हूं कि यह प्रवेश उल्लंघन का कारण नहीं है? – Krishter

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