Как вручную упаковать объект.NET как двойной интерфейс COM?
Я написал некоторый код C#, который возвращает объект.NET в неуправляемый код как IDispatch
использование указателя Marshal.GetIDispatchForObject
однако этот объект также реализует другие (не определенные в.NET) COM-интерфейсы. В неуправляемом мире QueryInterface
для этих интерфейсов работает нормально, однако, вызов методов для них никогда не нарушает мой код.NET и, похоже, возвращает только значения по умолчанию (0).
Можно ли маршалировать объект.NET как двойной интерфейс, чтобы его можно было использовать через IDispatch
или путем запроса для определенных интерфейсов? Мой тип публичный, ComVisible
и я пытался подать заявку [ClassInterface(ClassInterfaceType.AutoDual)]
без удачи
У меня не было проблем, заставляя вещи работать, используя UnmanagedType.Interface
маршалинг, однако, поддерживая IDispatch
также кажется проблематичным. Если есть простой способ "вручную" реализовать IDispatch
это также было бы приемлемым решением.
1 ответ
Вы можете использовать интерфейс ICustomQueryInterface. Это позволит вам возвращать интерфейсы IUnknown "вручную" и при этом пользоваться преимуществами реализации IDispatch, предоставляемой.NET. Так, например, если у вас есть неуправляемый интерфейс IUnknown "IMyUnknown", который содержит один метод (в примере называемый "MyUnknownMethod"), вы можете объявить свой класс.NET следующим образом:
[ComVisible(true)]
public class Class1 : ICustomQueryInterface, IMyUnknown
{
CustomQueryInterfaceResult ICustomQueryInterface.GetInterface(ref Guid iid, out IntPtr ppv)
{
if (iid == typeof(IMyUnknown).GUID)
{
ppv = Marshal.GetComInterfaceForObject(this, typeof(IMyUnknown), CustomQueryInterfaceMode.Ignore);
return CustomQueryInterfaceResult.Handled;
}
ppv = IntPtr.Zero;
return CustomQueryInterfaceResult.NotHandled;
}
// an automatic IDispatch method
public void MyDispatchMethod()
{
...
}
// the IMyUnknown method
// note you can declare that method with a private implementation
public void MyUnknownMethod()
{
...
}
}