Как вызвать метод частного COM-интерфейса, определенного в базовом классе?
Как я могу вызвать метод частного COM-интерфейса, определенного в базовом классе, из производного класса?
Например, вот интерфейс COM,IComInterface
(IDL):
[
uuid(9AD16CCE-7588-486C-BC56-F3161FF92EF2),
oleautomation
]
interface IComInterface: IUnknown
{
HRESULT ComMethod([in] IUnknown* arg);
}
Вот класс C #BaseClass
изOldLibrary
сборка, которая реализуетIComInterface
вот так (обратите внимание, что интерфейс объявлен как закрытый):
// Assembly "OldLibrary"
public static class OldLibrary
{
[ComImport(), Guid("9AD16CCE-7588-486C-BC56-F3161FF92EF2")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IComInterface
{
void ComMethod([In, MarshalAs(UnmanagedType.Interface)] object arg);
}
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
public class BaseClass : IComInterface
{
void IComInterface.ComMethod(object arg)
{
Console.WriteLine("BaseClass.IComInterface.ComMethod");
}
}
}
Наконец, вот улучшенная версия,ImprovedClass
который вытекает изBaseClass
, но объявляет и реализует свою собственную версиюIComInterface
потому что базаOldLibrary.IComInterface
недоступен:
// Assembly "NewLibrary"
public static class NewLibrary
{
[ComImport(), Guid("9AD16CCE-7588-486C-BC56-F3161FF92EF2")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IComInterface
{
void ComMethod([In, MarshalAs(UnmanagedType.Interface)] object arg);
}
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
public class ImprovedClass :
OldLibrary.BaseClass,
IComInterface,
ICustomQueryInterface
{
// IComInterface
void IComInterface.ComMethod(object arg)
{
Console.WriteLine("ImprovedClass.IComInterface.ComMethod");
// How do I call base.ComMethod here,
// otherwise than via reflection?
}
// ICustomQueryInterface
public CustomQueryInterfaceResult GetInterface(ref Guid iid, out IntPtr ppv)
{
if (iid == typeof(IComInterface).GUID)
{
ppv = Marshal.GetComInterfaceForObject(this, typeof(IComInterface), CustomQueryInterfaceMode.Ignore);
return CustomQueryInterfaceResult.Handled;
}
ppv = IntPtr.Zero;
return CustomQueryInterfaceResult.NotHandled;
}
}
}
Как мне позвонитьBaseClass.ComMethod
изImprovedClass.ComMethod
без размышлений?
Я мог бы использовать отражение, но в реальном случае использованияIComInterface
является сложным интерфейсом OLE с несколькими членами сложных сигнатур.
Я думал, что потому что обаBaseClass.IComInterface
а такжеImprovedClass.IComInterface
оба COM-интерфейсы с одинаковым GUID и одинаковыми сигнатурами методов, и естьЭквивалентность типа COM в .NET 4.0+, так что должен быть способ делать то, что мне нужно, без размышлений.
Другое требование заключается в том, чтоImprovedClass
должен быть получен изBaseClass
, потому что клиентский код C # ожидает экземплярBaseClass
, который он передает в код COM-клиента. Таким образом, сдерживаниеBaseClass
внутриImprovedClass
это не вариант.
[EDITED] Реальный сценарий, который включает в себя вывод изWebBrowser
а такжеWebBrowserSite
описаноВот.