enum ejemplos define c# c++ .net com com-interop

ejemplos - enum in model c#



¿Cuál es la forma correcta de llamar a los enumeradores COM en.NET? (3)

La firma adecuada para esto sería así:

void Next( uint celt, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] IFoo[] rgelt, out uint pceltFetched);

Según MSDN, al menos, no hay un mecanismo para generar esto automáticamente. Incluso si el IDL original para la interfaz tenía length_is aplicado a rgelt , esa información se pierde en el typelib. Por lo tanto, deberá editar el ensamblado de interoperabilidad manualmente.

Otra opción es definir esta interfaz en particular completamente a mano en su ensamblaje principal, y simplemente ignorar la versión de interoperabilidad generada. Recuerde que cuando realice conversiones en RCW, cualquier interfaz con un GUID coincidente (es decir, aquel para el cual QueryInterface tiene éxito) funcionará, por lo que puede tener varias interfaces administradas diferentes que presenten diferentes vistas de la misma interfaz COM.

Estoy llamando a una DLL COM provista externamente para la cual he generado una envoltura de interoperabilidad COM. En aras de la discusión, llamemos a la interfaz que quiero llamar IEnumFoo .

IEnumFoo tiene el patrón típico de enumerador COM:

HRESULT Next ( ULONG celt, IFoo** rgelt, ULONG* pceltFetched );

donde el primer parámetro es el número de resultados deseados, el segundo parámetro es un búfer al que se escriben los resultados, y el último parámetro describe la cantidad de resultados realmente escritos.

Cuando elijo "Agregar referencia" y señalo Visual Studio en esta DLL, genera un ensamblado de interoperabilidad COM con la siguiente firma:

void Next(uint, out IFoo, out uint)

Esto solo permite que el código .NET solicite un solo objeto a la vez, lo que puede agregar una cantidad significativa de sobrecarga al uso de estas API.

¿Hay algún mecanismo que pueda usar para generar una versión de Next que me permita proporcionar más IFoo "slots" arriba que harían feliz al Marshaler? (No soy reacio a editar el IL en el ensamblado de interoperabilidad a mano :))


No responde a su pregunta, sino una sugerencia para probar un enfoque diferente. Crearía un contenedor C ++ / CLI para enumerar a través de la interfaz COM en código no administrado (evitando así la tara de cálculo) y luego construir una List administrada u otro contenedor en el que devuelva sus objetos.

Es casi seguro que esto será más fácil que ajustar manualmente el IL del ensamblado de interoperabilidad y también puede depurarlo fácilmente. El código de C ++ no administrado será bastante simple, al igual que el contenedor administrado alrededor de eso.


Si el objeto que implementa esta interfaz es nativo, simplemente redefina la interfaz en su código como debería ser, asegurándose de usar los mismos atributos ComImport y Guid en la interfaz. A continuación, toma el objeto y el yeso a tu interfaz. Puede llamar a través de esa interfaz muy bien.

Recuerde: los ensambles de interoperabilidad no son mágicos, siempre puede definir una interfaz manualmente.