2010-03-04 20 views
5

Recientemente, pasé bastante tiempo escribiendo varios proyectos de extensiones de Visual Studio. Aunque todos los proyectos son código administrado para acceder a los servicios básicos de VS, aún es necesario trabajar con las interfaces COM de estilo antiguo.Directrices de recuento de referencia de interoperabilidad COM

Aquí se muestra un ejemplo:

var selectionTracker = (IVsMonitorSelection)serviceProvider.GetService(typeof(SVsShellMonitorSelection)); 
IntPtr ppHier; 
uint pitemid; 
IVsMultiItemSelect ppMIS; 
IntPtr ppSC; 
selectionTracker.GetCurrentSelection(out ppHier, out pitemid, out ppMIS, out ppSC))) 

como se puede ver esta llamada devuelve 2 punteros (ppHier y PPSC) y un ppMIS objeto. La pregunta es: ¿cómo debo hacer para jugar bien con el recuento de referencias COM?

Tengo entendido que en el mundo COM cuando un método devuelve un puntero a un objeto, este puntero es AddRef'ed antes de que se devuelva. Lo que significa que para evitar la fuga de objetos COM tengo que liberarlos cuando haya terminado de usarlos.

También asumo que lo que obtengo como objeto ya está envuelto en un RCW, que se ocupará de la liberación de referencia cuando esté finalizado.

Estas dos suposiciones aplicadas a la llamada anterior significarían que tengo que asegurarme de llamar a 'Marshal.Release' en mis 2 punteros, pero no debería hacer nada sobre el recuento de referencias con respecto al objeto devuelto.

Para reformular mi pregunta: asumiendo que los objetos COM que estoy usando están jugando con las reglas COM, ¿está el enfoque por encima de la forma correcta de manejar el recuento de referencias COM?

Respuesta

0

En este escenario particular que tendría que llamar Marshal.Release en los IntPtr variables de lo contrario no va a desaparecer. Por supuesto si le dices al marshaller que simplemente use el objeto (o un tipo específico) directamente, entonces no tendrás que preocuparte porque el RCW asegurará que el objeto se destruya en algún momento en el futuro (es decir, cuando se llame al finalizador el proceso de recolección de basura).

Por supuesto, el enfoque finalizador podría suceder en un punto no determinista en el tiempo por lo que si el objeto mantiene algún recurso que se necesita para deshacerse de lo ideal sería llamar Marshal.ReleaseComObject para disminuir su cuenta de referencia antes de la envoltura te libera por ti

Cuestiones relacionadas