Unable to initialize the IDXGIFactory object without errors

0

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?

c#
.net
com
dxgi
asked on Stack Overflow Nov 27, 2018 by LLENN • edited Nov 27, 2018 by LLENN

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0