I would like to know how to properly implement work with COM objects, the implementation of IUnknown interfaces, and also correctly marshall the arguments passed to the import functions from COM libraries.

At the moment I am interested in how to properly implement work with the dxgi library.

I looked at object inheritance, and everything converges to one, all DXGI interfaces DXGI inherited from IDXGIObject , and this interface is inherited from IUnknown . It would seem simple, to organize the IDXGIObject interface from it to inherit additional interfaces, and work with them. But, in my case, I simply do not understand how this is done correctly, and how to work with a method that takes 2 parameters, for example, this one:

 HRESULT CreateDXGIFactory( REFIID riid, void **ppFactory ); 

Yes, REFIID is just a typedef IID* REFIID , but again the question is what an IID and how to marshall it from to this method contained in the dxgi library.

All that occurred to me was about a realization that I didn’t check:

 [Guid("aec22fb8-76f3-4639-9be0-28eb43a67a2e")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IDXGIObject { long SetPrivateData( [In] Guid refGuid, [In] uint dataSize, [In] IntPtr data); long SetPrivateDataInterface( [In] ref Guid name, [In][MarshalAs(UnmanagedType.IUnknown)] object data); long GetPrivateData( [In] Guid name, [In][Out][MarshalAs(UnmanagedType.SysUInt)] ref uint outDataSize, [Out][MarshalAs(UnmanagedType.IUnknown)] IntPtr data); ... } 

In the work of such an implementation, I very much doubt it, because the whole thing looks suspiciously simple. And not sure about the correctness of the interface transfer from dxgi.h

 MIDL_INTERFACE("aec22fb8-76f3-4639-9be0-28eb43a67a2e") IDXGIObject : public IUnknown { public: virtual HRESULT STDMETHODCALLTYPE SetPrivateData( /* [annotation][in] */ __in REFGUID Name, /* [in] */ UINT DataSize, /* [annotation][in] */ __in_bcount(DataSize) const void *pData) = 0; virtual HRESULT STDMETHODCALLTYPE SetPrivateDataInterface( /* [annotation][in] */ __in REFGUID Name, /* [annotation][in] */ __in const IUnknown *pUnknown) = 0; virtual HRESULT STDMETHODCALLTYPE GetPrivateData( /* [annotation][in] */ __in REFGUID Name, /* [annotation][out][in] */ __inout UINT *pDataSize, /* [annotation][out] */ __out_bcount(*pDataSize) void *pData) = 0; virtual HRESULT STDMETHODCALLTYPE GetParent( /* [annotation][in] */ __in REFIID riid, /* [annotation][retval][out] */ __out void **ppParent) = 0; }; 

Did I manage to transfer the interface correctly? And how best to do it?

  • The attributes [In] and [Out] do not need to be written - they are not for you, but for the compiler. And it is better to replace IntPtr data with [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] byte[] data - Pavel Mayorov

0