#c_sharp #net #com #interop
Есть ли необходимость повторно указывать аттрибут типа интерфейса Com, если он наследуется от другого Com интерфейса, в котором уже был задан тип? Пример: [ComImport] [Guid("aec22fb8-76f3-4639-9be0-28eb43a67a2e")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IDXGIObject { long SetPrivateData([In] ref Guid name, [In] uint dataSize, IntPtr dataPtr); long SetPrivateDataInterface([In] ref Guid name, [In] [MarshalAs(UnmanagedType.IUnknown)] object unknownInterfaceObject); long GetPrivateData([In] ref Guid name, out int dataSize, out IntPtr dataPtr); long GetParent([In] ref Guid rIId, [Out] out object pParent); } Далее, его наследником будет IDXGIFactory: ////> /// /// An IDXGIFactory interface implements methods for generating DXGI objects (which handle fullscreen transitions). /// [ComImport] [Guid("7b7166ec-21c7-44ae-b21a-c9ae321ae369")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IDXGIFactory : IDXGIObject { ////// Enumerates the adapters (video cards). /// [PreserveSig] HResult EnumAdapters(uint numAdapter, [MarshalAs(UnmanagedType.IUnknown)] out object adapter); ////// Allows DXGI to monitor an application's message queue for the alt-enter key sequence (which causes the application /// to switch from windowed to fullscreen or vice versa). /// [PreserveSig] HResult MakeWindowAssociation(IntPtr windowHandle, uint flags); ////// Get the window through which the user controls the transition to and from fullscreen. /// [PreserveSig] HResult GetWindowAssociation(out IntPtr outHandleWindow); ////// Creates a swap chain. /// [PreserveSig] HResult CreateSwapChain(IntPtr lpIUnknown, IntPtr ptr, out IntPtr outPtr); ////// Create an adapter interface that represents a software adapter. /// [PreserveSig] HResult CreateSoftwareAdapter(IntPtr moduleHandle, out IntPtr outPtr); } Есть ли необходимость вновь писать аттрибут [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] для интерфейса наследника, если он тоже по сути является IUnknown?
Ответы
Ответ 1
Нужно, так как InterfaceTypeAttribute определен как не наследуемый: [System.AttributeUsage(System.AttributeTargets.Interface, Inherited=false)] [System.Runtime.InteropServices.ComVisible(true)] public sealed class InterfaceTypeAttribute : AttributeОтвет 2
Путем некоторых манипуляций удалось выяснить, в обязательном порядке стоит соблюдать следующие правила: Наследуемый объект должен переопределять декларацию интерфейса от которого наследуется, перед методами текущего метода, т.е. до их объявлений. (Спасибо за подсказку @MSDN.WhiteKnight). Интерфейс наследник в обязательном порядке должен иметь атрибут [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)], иначе будем иметь проблемы с доступом к памяти. Интерфейс наследник наследуется от интерфейса который для него является базовым лишь для удобства работы с данными интерфейсами. Таким образом, базовый интерфейс к примеру в данном случае это IDXGIObject выглядит так: ////// An IDXGIObject interface is a base interface for all DXGI objects; IDXGIObject supports associating caller-defined /// (private data) with an object and retrieval of an interface to the parent object. /// [Guid("aec22fb8-76f3-4639-9be0-28eb43a67a2e")] [ComImport] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IDXGIObject { ////// Sets an IUnknown interface as private data; this associates application-defined data with the object. /// [PreserveSig] HResult SetPrivateData(ref Guid name, uint dataSize, IntPtr dataPtr); ////// Set an interface in the object's private data. /// [PreserveSig] HResult SetPrivateDataInterface(ref Guid name, [MarshalAs(UnmanagedType.IUnknown)] object unknownInterfaceObject); ////// Get a pointer to the object's data. /// [PreserveSig] HResult GetPrivateData(ref Guid name, out int dataSize, out IntPtr dataPtr); ////// Gets the parent of the object. /// [PreserveSig] HResult GetParent(ref Guid rIId, out object pParent); } Далее от него к примеру наследуется IDXGIFactory определение необходимо задавать строго вот так: ////// /// An [Guid("7b7166ec-21c7-44ae-b21a-c9ae321ae369")] [ComImport] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IDXGIFactory : IDXGIObject { ///interface implements methods for generating DXGI objects (which handle fullscreen /// transitions). /// /// Sets an IUnknown interface as private data; this associates application-defined data with the object. /// [PreserveSig] new HResult SetPrivateData(ref Guid name, uint dataSize, IntPtr dataPtr); ////// Set an interface in the object's private data. /// [PreserveSig] new HResult SetPrivateDataInterface(ref Guid name, [MarshalAs(UnmanagedType.IUnknown)] object unknownInterfaceObject); ////// Get a pointer to the object's data. /// [PreserveSig] new HResult GetPrivateData(ref Guid name, out int dataSize, out IntPtr dataPtr); ////// Gets the parent of the object. /// [PreserveSig] new HResult GetParent(ref Guid rIId, out object pParent); ////// Enumerates the adapters (video cards). /// [PreserveSig] HResult EnumAdapters(uint numAdapter, [MarshalAs(UnmanagedType.IUnknown)] out object adapter); ////// Allows DXGI to monitor an application's message queue for the alt-enter key sequence (which causes the application /// to switch from windowed to fullscreen or vice versa). /// [PreserveSig] HResult MakeWindowAssociation(IntPtr windowHandle, uint flags); ////// Get the window through which the user controls the transition to and from fullscreen. /// [PreserveSig] HResult GetWindowAssociation(out IntPtr outHandleWindow); ////// Creates a swap chain. /// [PreserveSig] HResult CreateSwapChain(object iUnknown, ref DxgiSwapChainDesc swapChainDesc, [MarshalAs(UnmanagedType.IUnknown)] out object dxgiSwapChainObject); ////// Create an adapter interface that represents a software adapter. /// [PreserveSig] HResult CreateSoftwareAdapter(IntPtr moduleHandle, out IntPtr outPtr); } Все проблемы себя исчерпали, и код стал работать так как должен.
Комментариев нет:
Отправить комментарий