2012-07-09 22 views
8

Yönetilmeyen bir geri çağrıyı yönetilmeyen bir TCP alıcısına iletmem gerekiyor. Uygulamanın ömrü boyunca bulunması gereken bir iş parçacığı olduğundan, toplanan çöpleri almasını engellemem gerekiyor. Her yerde, işlev işaretleyicilerini sabitlemenin gerekli olmadığını ve GCHandle.Alloc'un çöp toplanmasını önleme görevini yapacağını okudum.Bir işlev işaretçisini sabitleme

Ama bu verilen bir şey mi? Bu kodu barındıran AppPool'un erişim ihlali ile çöktüğünü gördüm. Neden işlev hatası toplayıcı çöp toplandığından bu hatanın meydana geldiğinden şüphe etmemeliyim?

Bu post, bu gerçeği desteklemektedir.

Güncelleme: Kazaları önemli ölçüde azalttığı görülüyor. Bu yaklaşımla ilgili bir problem var mı?

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

Temsilci nesnesini statik bir değişkende saklamak yeterlidir. Yerel kod, birçok nedenden ötürü erişim ihlalleriyle bombalanabilir. –

+0

Tam olarak bunu yaptım. Çöp toplamadan şüphelenmeye neden olma eğiliminde olmanın sebebi, erişim ihlalinin düzensiz gerçekleşmesidir. Ve daha da önemlisi, çökme dökümündeki çağrı yığını, yerli dll'yi clr.dll ve ardından yığının üstündeki kernel32.dll tarafından görebiliyorum. Bu sipariş tutarlıdır. – Krishter

cevap

8

Ne yapmaya önermek tam olarak ne yapmak - temsilci üzerinde ama hiçbir çivileme ile GCHandle.Alloc - ve 2,0 birçok farklı platformlarda ve .NET sürümleri hakkında geniş kullanımda herhangi bir sorun olmadı - 4. Something gibi: FunctionPointer ile

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

sonra yerli koda geçti ve DelegateHandle sonraki temizlik için tuttu.

Bu en iyi başvuru kaynağı: http://msdn.microsoft.com/en-us/library/367eeye0(v=vs.80).aspx.

Bu başvuruyla çelişen bir ileti noktasında hiçbir şey yok - çöp toplamadan delegeyi korumanız gerekmiyor, yalnızca iğneleme gerekli değil.

+0

Yığın nesnelerinden farklı olarak, bir const konumunda bulundukları için, işlevler için adres-pinning gerekli değil mi? JIT'd henüz btw olmasaydı, hangi fonksiyon bir işlevi var? – Dai

+2

GetFunctionPointerForDelegate çağrısının sabit bir giriş noktası olan küçük bir sıra dizisi oluşturduğunu düşünüyorum, ancak delegenin taşınması durumunda saplama yine de nasıl çağırılacağını bilir. Bu nedenle dışa aktarılan işlev işaretçisi, temsilci nesnenin adresini (sabitlenmiş bir dizi veya yapı üyesinin aksine) doğrudan dışa aktarmaz. Dışa aktarılan 'yerel' işlevin yerel -> yönetilen geçişi de uygulaması gerektiğini unutmayın. – Govert

+0

Bu tam olarak yaptığım şey. Maalesef erişim ihlali hala gerçekleşir. Bu şekilde söyleyeyim. Bu erişim ihlali için neden OLMADIĞINI nasıl emin olabilirim? – Krishter

İlgili konular