I have definitions of com interfaces, but when I try to initialize objects marked with
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
always get an exception like AccessViolationException
Trying to create an IDXGIFactory
object:
public static class Manager
{
private static Guid _iidDxgiFactory = __uuidof<IDXGIFactory>();
//private static Guid _iidDxgiFactory1 = __uuidof<IDXGIFactory1>();
public static HResult CreateDxgiFactory(out IDXGIFactory factory)
{
HResult result = CreateDXGIFactory(ref _iidDxgiFactory, out object tmpFactoryObject);
factory = tmpFactoryObject as IDXGIFactory;
return result;
}
[DllImport("dxgi.dll")]
private static extern HResult CreateDXGIFactory(ref Guid refIId, out object factoryObject);
[DllImport("dxgi.dll")]
private static extern HResult CreateDXGIFactory1(ref Guid refIId, out object factory1Object);
internal static Guid __uuidof<T>()
{
return typeof(T).GUID;
}
}
The interface definitions are as follows:
/// <summary>
/// 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.
/// </summary>
[Guid("aec22fb8-76f3-4639-9be0-28eb43a67a2e")]
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IDXGIObject
{
/// <summary>
/// Sets an IUnknown interface as private data; this associates application-defined data with the object.
/// </summary>
[PreserveSig]
HResult SetPrivateData(ref Guid name, uint dataSize, IntPtr dataPtr);
/// <summary>
/// Set an interface in the object's private data.
/// </summary>
[PreserveSig]
HResult SetPrivateDataInterface(ref Guid name,
[MarshalAs(UnmanagedType.IUnknown)] object unknownInterfaceObject);
/// <summary>
/// Get a pointer to the object's data.
/// </summary>
[PreserveSig]
HResult GetPrivateData(ref Guid name, out int dataSize, out IntPtr dataPtr);
/// <summary>
/// Gets the parent of the object.
/// </summary>
[PreserveSig]
HResult GetParent(ref Guid rIId, out object pParent);
}
where HResult
just a enum with error codes from winerror.h
And i think following interface IDXGIFactory
can be defined as:
/// <inheritdoc />
/// <summary>
/// An <see cref="T:Himiko.DXGI.Interfaces.IDXGIFactory" /> interface implements methods for generating DXGI objects (which handle fullscreen
/// transitions).
/// </summary>
[Guid("7b7166ec-21c7-44ae-b21a-c9ae321ae369")]
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IDXGIFactory : IDXGIObject
{
/// <summary>
/// Enumerates the adapters (video cards).
/// </summary>
[PreserveSig]
HResult EnumAdapters(uint numAdapter, [MarshalAs(UnmanagedType.IUnknown)] out object adapter);
/// <summary>
/// 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).
/// </summary>
[PreserveSig]
HResult MakeWindowAssociation(IntPtr windowHandle, uint flags);
/// <summary>
/// Get the window through which the user controls the transition to and from fullscreen.
/// </summary>
[PreserveSig]
HResult GetWindowAssociation(out IntPtr outHandleWindow);
/// <summary>
/// Creates a swap chain.
/// </summary>
[PreserveSig]
HResult CreateSwapChain(IntPtr lpIUnknown, IntPtr ptr,
out IntPtr outPtr); // FIXME: create a definitions for IDXGISwapChain
/// <summary>
/// Create an adapter interface that represents a software adapter.
/// </summary>
[PreserveSig]
HResult CreateSoftwareAdapter(IntPtr moduleHandle, out IntPtr outPtr);
/// <summary>
/// Sets an IUnknown interface as private data; this associates application-defined data with the object.
/// </summary>
[PreserveSig]
new HResult SetPrivateData(ref Guid name, uint dataSize, IntPtr dataPtr);
/// <summary>
/// Set an interface in the object's private data.
/// </summary>
[PreserveSig]
new HResult SetPrivateDataInterface(ref Guid name,
[MarshalAs(UnmanagedType.IUnknown)] object unknownInterfaceObject);
/// <summary>
/// Get a pointer to the object's data.
/// </summary>
[PreserveSig]
new HResult GetPrivateData(ref Guid name, out int dataSize, out IntPtr dataPtr);
/// <summary>
/// Gets the parent of the object.
/// </summary>
[PreserveSig]
new HResult GetParent(ref Guid rIId, out object pParent);
}
However, if you try to call such code, it turns out that the call to CreateDXGIFactory
is successful, but then when you access this interface, you get a memory read error at 0x00000000
.
I do not know why this happens, but if you remove the attribute [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
then this object is accessed successfully. But when you try to obtain the address of the object IUnknown
, Marshal
reports that the interface is not valid as IUnknown
.
How to properly implement use of the COM Api?
User contributions licensed under CC BY-SA 3.0