c# com idispatch

Implementando IDispatch en c#



com (2)

Debería poder usar la reflexión en el tipo COM para obtener la lista de métodos.

Type comType = Type.GetTypeFromProgID("ProgID.Test"); MethodInfo[] methods = comType.GetMethods();

Estoy escribiendo un código de prueba para emular el código no administrado llamando a mi implementación c # de un objeto COM vinculante tardío. Tengo una interfaz que se declara como un tipo IDispatch como a continuación.

[Guid("2D570F11-4BD8-40e7-BF14-38772063AAF0")] [InterfaceType(ComInterfaceType.InterfaceIsDual)] public interface TestInterface { int Test(); } [ClassInterface(ClassInterfaceType.AutoDual)] public class TestImpl : TestInterface { ... }

Cuando utilizo el siguiente código para llamar a la función GetIDsOfNames de IDispatch

.. //code provided by Hans Passant Object so = Activator.CreateInstance(Type.GetTypeFromProgID("ProgID.Test")); string[] rgsNames = new string[1]; int[] rgDispId = new int[1]; rgsNames[0] = "Test"; //the next line throws an exception IDispatch disp = (IDispatch)so;

Donde IDispatch se define como:

//code provided by Hans Passant [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("00020400-0000-0000-C000-000000000046")] private interface IDispatch { int GetTypeInfoCount(); [return: MarshalAs(UnmanagedType.Interface)] ITypeInfo GetTypeInfo([In, MarshalAs(UnmanagedType.U4)] int iTInfo, [In, MarshalAs(UnmanagedType.U4)] int lcid); void GetIDsOfNames([In] ref Guid riid, [In, MarshalAs(UnmanagedType.LPArray)] string[] rgszNames, [In, MarshalAs(UnmanagedType.U4)] int cNames, [In, MarshalAs(UnmanagedType.U4)] int lcid, [Out, MarshalAs(UnmanagedType.LPArray)] int[] rgDispId); }

Se lanza una InvalidCastException. ¿Es posible convertir la interfaz de CA # en IDispatch?


Debe registrar su ensamblaje con regasm, y debe marcar las clases a las que desea acceder desde COM con el atributo [ComVisible]. También puede necesitar generar y registrar una biblioteca de tipos usando tlbexp (para generar) y tregsvr para registrarla.

Además (desde una perspectiva de Win32) "disp = (IDispatch) obj" no es lo mismo que "disp = obj como IDispatch" - usar el operador ''como'' realmente llama al método QueryInterface en el objeto para obtener el puntero a la interfaz solicitada , en lugar de tratar de lanzar un objeto a la interfaz.

Por último, usar el tipo "dinámico" de c # probablemente sea más parecido a lo que los otros chicos están haciendo para acceder a tu clase.