Deploying IDispatch in C #

I am writing some test code to emulate unmanaged code that calls my C # implementation for late binding of a COM object. I have an interface declared as an IDispatch type, as shown below.

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

When I use the code below to call the IDispatch function GetIDsOfNames

  .. //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; 

Where IDispatch is defined as:

  //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); } 

An InvalidCastException is thrown. Is it possible to include a C # interface in IDispatch?

+6
source share
2 answers

You need to register the assembly with regasm, and you need to mark the classes you want to get from COM with the [ComVisible] attribute. You may also need to create and register a type library using tlbexp (for generation) and tregsvr to register it.

Also (from Win32's point of view) "disp = (IDispatch) obj" does not match "disp = obj as IDispatch" - using the "as" operator actually calls the object's QueryInterface method to get a pointer to the requested interface, instead of trying to pass object in interface.

Finally, using C # type 'dynamic' is likely to be closer to what other guys are doing to access your class.

+1
source

To get a list of methods, you should simply use reflection in the COM type.

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

Source: https://habr.com/ru/post/901140/


All Articles