Necesito pasar una devolución de llamada administrada a un receptor TCP no administrado. Como es un hilo que debe existir durante el tiempo de vida de la aplicación, debo evitar que se recolecte la basura. He leído en todas partes que no se requieren punteros de función de fijación y el GCHandle.Alloc hará el trabajo de prevenir la recolección de basura.Pin un puntero a la función
¿Pero esto es un hecho? He visto que la AppPool que aloja este código se bloquea con una infracción de acceso. ¿Por qué no debería sospechar que este error ocurre porque el puntero a la función fue basura?
Esto post es compatible con este hecho.
Actualización: Esto parece haber reducido los bloqueos considerablemente. ¿Hay algún problema con este enfoque?
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);
Almacenar el objeto delegado en una variable estática es suficiente. El código nativo puede bombardear con violaciones de acceso por muchos otros motivos. –
He hecho exactamente eso. La razón por la que estoy tendiendo a sospechar que la recolección de basura es la causa es porque la violación de acceso ocurre de forma errática. Y, lo que es más importante, la pila de llamadas en el volcado de bloqueo puedo ver el dll nativo seguido de clr.dll y luego kernel32.dll en la parte superior de la pila. Esta orden es consistente. – Krishter