Calling a member of IDispatch COM interface from C#

后端 未结 2 967
感情败类
感情败类 2020-12-03 12:49

I wanted to call the GetIdsOfNames function from a COM object that implements the IDispatch interface in c#. I\'ve written the following code but it fails with the DISP_E_UN

相关标签:
2条回答
  • 2020-12-03 13:18

    No you cannot, because InvokeMember internally uses GetIDsOfNames, and this one only checks actual methods, not the first 6 in IDispatch. Or in other words, GetIDsOfNames cannot be invoked using IDispatch's method Invoke. That is how COM works.

    0 讨论(0)
  • 2020-12-03 13:45

    Yes, doesn't work, the RCW doesn't expose the IDispatch methods. You have to obtain the IDispatch interface reference explicitly. This worked well:

    using System;
    using System.Runtime.InteropServices;
    using System.Runtime.InteropServices.ComTypes;
    
    class Program {
        static void Main() {
            Object so = Activator.CreateInstance(Type.GetTypeFromProgID("SAPI.SpVoice"));
            string[] rgsNames = new string[1];
            int[] rgDispId = new int[1];
            rgsNames[0] = "Speak";
            IDispatch disp = (IDispatch)so;
            Guid dummy = Guid.Empty;
            disp.GetIDsOfNames(ref dummy, rgsNames, 1, 0x800, rgDispId);
            Console.WriteLine(rgDispId[0]);
        }
    
        [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);
        }
    }
    
    0 讨论(0)
提交回复
热议问题