Alternative title: WinRT support for IDirect3DDevice

我有一个应用程序,它使用"Direct3D11CaptureFramePool"类来捕获应用程序窗口的内容,如下所示(link)

我想把这个例子移植到Net6.0

这里介绍了如何移植WinRT代码

How can i port this code to NET 6.0

    uint hr = CreateDirect3D11DeviceFromDXGIDevice(dxgiDevice.NativePointer, out IntPtr pUnknown);
    if (hr == 0)
    {
        device = Marshal.GetObjectForIUnknown(pUnknown) as IDirect3DDevice;
        Marshal.Release(pUnknown);
    }

IDrect3DDEvice没有FromAbi方法,如here所述

Edit:

我有接口类型,我有一个指向IUnknown对象的指针,但我无法获取实例,因为为IUnknown指针获取对象的代码已更改.没有 Windows.Graphics.DirectX.Direct3D11.IDirect3DDevice.FromAbi(pUnknown)

Edit 2:

我创建了一个回购示例来重现这个问题:

这段代码适用于Net4.8,但不适用于Net6.我相信,因为

internal class Program
{

[DllImport(
        "d3d11.dll",
        EntryPoint = "CreateDirect3D11DeviceFromDXGIDevice",
        SetLastError = true,
        CharSet = CharSet.Unicode,
        ExactSpelling = true,
        CallingConvention = CallingConvention.StdCall
        )]
static extern UInt32 CreateDirect3D11DeviceFromDXGIDevice(IntPtr dxgiDevice, out IntPtr graphicsDevice);

static void Main(string[] args)
{

    using var sharpDxDevice = new SharpDX.Direct3D11.Device(SharpDX.Direct3D.DriverType.Hardware, SharpDX.Direct3D11.DeviceCreationFlags.BgraSupport);
    IDirect3DDevice direct3dDevice = CreateDirect3DDeviceFromSharpDXDevice(sharpDxDevice);

    // this will throw internal cast exception 
    using var framePool = Direct3D11CaptureFramePool.CreateFreeThreaded(
                        direct3dDevice,
                        DirectXPixelFormat.B8G8R8A8UIntNormalized,
                        2,
                        new SizeInt32(64, 64));

}

private static IDirect3DDevice CreateDirect3DDeviceFromSharpDXDevice(SharpDX.Direct3D11.Device sharpDxDevice)
{
    IDirect3DDevice device = null;
    using (var dxgiDevice = sharpDxDevice.QueryInterface<SharpDX.DXGI.Device3>())
    {
        uint hr = CreateDirect3D11DeviceFromDXGIDevice(dxgiDevice.NativePointer, out IntPtr pUnknown);
        if (hr == 0)
        {
            // with NET 6 there should be something like 
            // IDirect3DDevice.FromAbi(pUnknown)
            // see here https://github.com/microsoft/CsWinRT/blob/master/docs/interop.md#create-rcw
            device = Marshal.GetObjectForIUnknown(pUnknown) as IDirect3DDevice;
            Marshal.Release(pUnknown);
        }
    }
    return device;
}
}

推荐答案

具有NET 6和CsWinRT,您可以这样编写CreateDirect3DDeviceFromSharpDXDevice函数:

private static IDirect3DDevice CreateDirect3DDeviceFromSharpDXDevice(SharpDX.Direct3D11.Device sharpDxDevice)
{
    if (CreateDirect3D11DeviceFromDXGIDevice(sharpDxDevice.NativePointer, out var punk) != 0)
        return null;

    return WinRT.MarshalInterface<IDirect3DDevice>.FromAbi(punk);
}

.net相关问答推荐

.NET 中两个子字符串之间的非贪婪正则表达式匹配

System.IO.Directory.Exists 在 LINQ 语句中失败,但在 foreach 循环中没有

在 WP7 中将 List 转换为 ObservableCollection

判断 Windows 路径中是否存在可执行文件

标签从右向左增长

.NET 中的线程安全集合

有什么方法可以在不重新编译的情况下覆盖 .NET Windows 服务名称?

如何从 .NET 中的流中获取 MemoryStream?

为什么使用 ImmutableList 而不是 ReadOnlyCollection?

我可以在没有两个查询的情况下通过布尔标准将 IEnumerable 一分为二吗?

如何在 C# 中将 null 值设置为 int?

在 C#/.NET 中组合路径和文件名的最佳方法是什么?

Environment.GetFolderPath(...CommonApplicationData) 在 Vista 上仍然返回C:\Documents and Settings\

如何使用 DateTime 指定一天中的最晚时间

为什么甚至可以更改私有成员,或使用反射在 C# 中运行私有方法?

SqlBulkCopy 的推荐批量大小是多少?

如何将 .NET 应用程序编译为本机代码?

如何将 MailMessage 对象作为 *.eml 或 *.msg 文件保存到磁盘

您可以将 Microsoft Entity Framework 与 Oracle 一起使用吗?

连接字符串而不是使用一堆 TextBlocks